Tutorial :C# Bestpractice: Writing a method that returns a value in depdency of the method parameter that is a part of the class itself



Question:

At first sorry for my really bad title! If you have a better title just change it or make a comment =)

I have this class:

public class Config  {      public Provider1 Provider1 { get; set; }      public Provider2 Provider2 { get; set; }      public Provider3 Provider3 { get; set; }      public Provider4 Provider4  { get; set; }      public Provider5 Provider5 { get; set; }        public int GetNumber(string provider)      {          ...      }  }  

Each provider has a Number property:

public interface IProvider  {      int Number{ get; set; }  }  

In dependency of the provider I want to return the Number of the provider.

How would you do that?

I do not want to use a big switch block.


Solution:1

public interface IProvider  {    int Number {get;set;}  }    public class Config  {       public int GetNumber<T>() where T : IProvider       {           // code to find the provider you want           IProvider foundProvider = ProviderFactoryMethodHere(typeof(T));             return foundProvider.Number;       }  }  

Now all of your provider classes need to implement the IProvider interface and you need to implement a factory that will return the correct provider to you given the type that you've requested in the generic method.

// Test code example  Config configImpl = new Config();  int numberOfProvider = configImpl.GetNumber<Provider1>();  Assert.Equal(1, numberOfProvider);  

I'll add a simple ProviderFactoryMethod example. Note that we could also make this method generic instead of passing the type as a parameter, but I'll leave the example as is.

public IProvider ProviderFactoryMethodHere(Type providerRequested)  {      Dictionary <Type, IProvider> providerDict;      if (providerDict == null)      {        // populate dictionary with providers, keyed by their type        providerDict = new Dictionary<Type, IProvider>();        providerDict.Add(typeof(Provider1), new Provider1());          // repeat for all providers, this is pretty simple but definitely works        // we could use other ways of holding on to your provider instances      }      if (providerDict.HasKey(providerRequested))      {          return providerDict[providerRequested];      }      // could throw exception here if you want to use that kind of error      // handling, but we'll just return null for now      return null;  }  

Cheers.


Solution:2

Add them to a dictionary keyed off the string that identifies the provider.

IDictionary<string, IProvider> providers = new Dictionary<string, IProvider>();  

You can then get the values from the dictionary by checking if the dictionary contains the value passed into the GetNumber method. If it's there, you can just grab it out of the dictionary and call the Number property on the provider.

return providers[provider].Number;

Note that when you're defining the dictionary, IProvider needs to be the base class which all the providers inherit from.


Solution:3

Ideally you want all of your Providers to inherit from a single base class (or interface) that provides the Number of each.

abstract class Provider {     public int Number { get; set; }  }    class Provider1 : Provider { ... }  

Then you can dump all of your Providers in a hash table keyed by whatever that string is you're using. For example:

public class Config  {     Dictionary<string, Provider> _providers = new Dictionary<string, Provider>();       // .. all of your providers ..       public int GetNumber(string provider)     {        if (!_providers.HasKey(provider))           throw ArgumentException();        return _providers[provider].Number;     }  }  


Solution:4

Create an interface.

IGiveANumberbackable { GetNumber(); }

Implement this in your classes.

Call this method on your class instead of GetNumber()


Solution:5

Is the provider's number a property of a base class or interface that all providers implement, or is it a property of its position in the config class?

edit

If it's a property of the provider, then the right way to access it is through the provider. In other words, Config should return some child of IProvider (or whatever you call it), and the caller can then chain to its Number property.

edit

Part of the problem is that you have enumerated property names ("prop1", "prop2", etc). Why not replace this with an indexer or a method that takes an index?

Another issue is that you seem to want to look up the Number by provider name, but there's no place shown where a name exists. Do you mean the class name?


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »