.Net for known return type but unknown type / number of parameters

Is there a way to specify in the interface a known return type, but an unknown parameter number / type.

The reason I'm asking is because I'm using Windows Azure table storage, and each table will have different section keys and rows with different input values.

I am creating an ITableOperations interface, the code will be something like this:

 interface ITableOperations<T> where T : Azure.AzureTableEntity { // Key specification string PartitionKey(/* ? What should go here */); // Key specification string RowKey(/* ? What should go here */); } 

And the table of elements ... For another table, the input parameters will be different

 public class ScheduledItem : ITableOperations<ScheduledPostEntity> { public string PartitionKey(Guid userGuid) { return userGuid.ToString(); } public string RowKey(DateTime dateScheduled) { return dateScheduled.ReverseTicks(); } } 
+6
source share
4 answers

C # supports multiple parameters as an array using the params .

You can do it:

 interface ITableOperations<T> where T : Azure.AzureTableEntity { // Key specification string PartitionKey(params object[] data); // Key specification string RowKey(params object[] data); } 

If you already know alternate options, you can use overloading. Suppose you have a method that can get a string or Guid or both, you can do this:

  string PartitionKey(Guid guid); string PartitionKey(string str); string PartitionKey(Guid guid, string str); 

If you are using C # 4, you can use optional parameters:

  string PartitionKey(Guid guid = default(Guid), string str = null); 
+2
source

You can define one parameter that will be an array. This array will contain name / value pairs and can have as many as you need. I think this will give you the flexibility you are looking for.

+1
source

This will not yet show you the correct list of parameters for DoStuff (you will only see params object[] ), but it will be as flexible as you get. Note that I implemented the method explicitly in the implementation class, so you do not see it in Intellisense if "foo" is declared as Foo , not IFoo .

 class Program { static void Main(string[] args) { IFoo foo = new Foo(); foo.DoStuff(Guid.NewGuid()); } } public interface IFoo { void DoStuff(params object[] args); } public class Foo : IFoo { public void DoStuff(Guid arg) { } void IFoo.DoStuff(params object[] args) { if (args.Length != 1) throw new ArgumentException("args"); if (args[0].GetType() != typeof(Guid)) throw new ArgumentException("args"); DoStuff((Guid)args[0]); } } 
+1
source

You can try to have a very common interface. For instance:

 interface ITableOperations<T, P, R> where T : Azure.AzureTableEntity { string PartitionKey(P partitionKey); string RowKey(R rowKey); } 

Then your implementation could be:

 public class ScheduledItem : ITableOperations<ScheduledPostEntity, Guid, DateTime> { public string PartitionKey(Guid userGuid) { return userGuid.ToString(); } public string RowKey(DateTime dateScheduled) { return dateScheduled.ReverseTicks(); } } 

EDIT:

Looking at some of your comments, since I originally wrote this answer, you could come to it from a different angle. PartitionKey and RowKey will not change on your object after its creation, so I would almost exclude these specific functions from this class and move it to the class constructors that inherit from AzureTableEntity . eg.

 public class ScheduledPostEntity : Azure.AzureTableEntity { private Guid _userGuid; private DateTime _dateScheduled; public ScheduledPostEntity() { // Needed for deserialisation from Azure Table Storage } public ScheduledPostEntity(Guid userGuid, DateTime dateScheduled) { _userGuid = userGuid; _dateScheduled = dateScheduled; } public string PartitionKey { get { return _userGuid.ToString(); } set { _userGuid = Guid.Parse(value); } } public string RowKey { get { return _dateScheduled.ReverseTicks(); } set { _dateScheduled = value.FromReverseTicks(); } } // These are functions to avoid them being saved as additional properties // in Azure Table Storage. Sometimes you can get away with them being // read only properties, but it depends on the type. public DateTime DateScheduled() { return _dateScheduled; } public Guid UserGuid() { return _userGuid; } } 

This has the advantage that whenever you create these objects, you know the minimum requirements for saving the object. It also prevents you from messing with things that will change your PCs and RCs.

+1
source

Source: https://habr.com/ru/post/888168/


All Articles