Introduction
In many cases, developers have a demand to call methods testing some conditions before, like, if
or switch
statements. In most cases, developers call different methods on different conditions. And sometimes, developers need to call different methods either in loops or consequently. All cases mentioned above are covered by this article. Here, you can find several C# code examples that demonstrate how to solve such tasks in an efficient manner. Hope this article will be helpful.
Conditional Invoking with Reflection
Let�s say we need to call different methods based on the value of a string
. We can easily do this using an if
statement:
if (key == "Key1")
{
this.method1();
}
else if (key == "Key2")
{
this.method2();
}
If we have to compare three or more values, we can use a switch
statement:
switch(key)
{
case "key1":
this.method1();
break;
case "key2":
this.method2();
break;
case "key3":
this.method3();
break;
default:
this.defMethod();
break;
}
But what if we have to test out ten or twenty or however many values and call the different methods for different values? We can still use the examples above for sure, but we also can use the following. Let�s define a naming convention for methods that we are going to call in such a manner that the method�s name will contain a compared value or any part of it, just like the following example:
this.Key1Method();
this.Key2Method();
this.Key3Method();
and so on. So we can use the following code to call these methods:
Type t = typeof(MyClass);
string key = "Key1";
t.InvokeMember( key + "Method",
BindingFlags.DeclaredOnly | BindingFlags.InvokeMethod | BindingFlags.Instance,
null, this, null);
Here, MyClass
is the name of the class that actually contains all those methods, and the InvokeMember
is a standard .NET Framework method to invoke any method in run-time based on Reflection information. The proposed approach is very easy to modify to use methods with parameters too. You can find all necessary information about the InvokeMember
in the Visual Studio .NET�s help. You can also not only use string values as a variable part of a method�s name but any type that you can represent as a string
using the standard ToString()
method as well.
This sample code could seem slower as long as it uses reflection. But it saves a lot of the developer�s time and provides a compact, flexible, and easily manageable code, not saying that it also may prevent unexpected mistakes usual to large if
or switch
statements.
Conditional Invoking with Delegates
Let�s solve the same task using delegates. First of all, let�s define a delegate
type for our methods. Guess it is not necessary to mention that all methods should expose the same signature.
delegate void MethodToInvoke();
Then, let�s create a so called Table of Calling using a standard Hashtable
for instance.
Hashtable methods = new Hashtable();
methods.Add("Key1", new MethodToInvoke(Key1Method));
methods.Add("Key2", new MethodToInvoke(Key2Method));
methods.Add("Key3", new MethodToInvoke(Key3Method));
And since we successfully made all preparations, finally we can call any of our "key" methods very simply, based on the value of the key variable:
string key = "Key1";
((MethodToInvoke)methods[key])();
Cycling Invoking
Using the pattern described above, we can easily implement a cycling methods invoking, that is a sequential calling of methods in a loop. Let�s see the following code:
for (int i=0; i<methods.Count; i++)
{
((MethodToInvoke)methods[i])();
}
That approach may be useful, for example, when you develop using the Pipeline Design Pattern and require calling several methods one by one. You may say that it�s very similar to what multicast delegates do when you initialize them with the +=
operator. That�s true. But let�s figure out a difference. Multicast delegates must have the void
return type. So you can�t use it if you want a delegate to return something. But the proposed approach allows you to do this easily:
delegate bool MethodToInvoke();
...
for (int i=0; i<methods.Count; i++)
{
if ( true != ((MethodToInvoke)methods[i])() )
break;
}
Conclusion
In this article, I have shortly described several approaches of method calling using such features of the .NET Framework and C# language as Reflection and delegates. Using these features lets developers increase the code flexibility, readability and manageability, and sometimes allows to prevent some mistakes connected with if
and switch
statements. I could bring much more examples of code using the concepts described. But the purpose of this article is just to illustrate a common idea of using delegates and reflection in cases of conditional method invoking. I guess that the goal is pretty much covered by this article.