使用委托和反射条件调用方法






4.68/5 (19投票s)
2005年1月25日
3分钟阅读

71947

2
本文档介绍如何使用 C# 和 .NET Framework 的委托和反射等功能来实现方法的条件或循环调用。本文档包含许多带有注释的 C# 代码示例。
引言
在许多情况下,开发人员需要调用方法之前测试一些条件,例如 if
或 switch
语句。 在大多数情况下,开发人员在不同的条件下调用不同的方法。 有时,开发人员需要循环或连续地调用不同的方法。 本文涵盖了上述所有情况。 在这里,您可以找到几个 C# 代码示例,演示如何以有效的方式解决此类任务。 希望这篇文章对您有所帮助。
使用反射的条件调用
假设我们需要根据 string
的值调用不同的方法。 我们可以使用 if
语句轻松做到这一点
if (key == "Key1")
{
this.method1();
}
else if (key == "Key2")
{
this.method2();
}
如果我们需要比较三个或更多值,我们可以使用 switch
语句
switch(key)
{
case "key1":
this.method1();
break;
case "key2":
this.method2();
break;
case "key3":
this.method3();
break;
default:
this.defMethod();
break;
}
但是,如果我们需要测试十个或二十个或更多的值,并为不同的值调用不同的方法怎么办? 我们仍然可以肯定地使用上面的例子,但我们也可以使用以下方法。 让我们为我们要以这种方式调用的方法定义一个命名约定,使方法名称包含一个比较值或它的任何部分,就像下面的例子一样
this.Key1Method();
this.Key2Method();
this.Key3Method();
等等。 所以我们可以使用以下代码来调用这些方法
Type t = typeof(MyClass);
string key = "Key1";
t.InvokeMember( key + "Method",
BindingFlags.DeclaredOnly | BindingFlags.InvokeMethod | BindingFlags.Instance,
null, this, null);
在这里,MyClass
是实际包含所有这些方法的类的名称,InvokeMember
是一个标准的 .NET Framework 方法,用于在运行时基于反射信息调用任何方法。 所提出的方法很容易修改为使用带参数的方法。 您可以在 Visual Studio .NET 的帮助文件中找到有关 InvokeMember
的所有必要信息。 您还可以不仅使用字符串值作为方法名称的可变部分,还可以使用可以使用标准 ToString()
方法表示为 string
的任何类型。
只要此示例代码使用反射,它看起来可能比较慢。 但它节省了开发人员的大量时间,并提供了紧凑、灵活且易于管理的代码,更不用说它还可以避免大型 if
或 switch
语句中常见的意外错误。
使用委托的条件调用
让我们使用委托来解决相同的任务。 首先,让我们为我们的方法定义一个 delegate
类型。 我想没有必要提及所有方法都应该公开相同的签名。
delegate void MethodToInvoke();
然后,让我们使用标准的 Hashtable
来创建一个所谓的调用表。
Hashtable methods = new Hashtable();
methods.Add("Key1", new MethodToInvoke(Key1Method));
methods.Add("Key2", new MethodToInvoke(Key2Method));
methods.Add("Key3", new MethodToInvoke(Key3Method));
由于我们成功地完成了所有准备工作,最后我们可以非常简单地根据 key 变量的值来调用我们的任何“key”方法
string key = "Key1";
((MethodToInvoke)methods[key])();
循环调用
使用上面描述的模式,我们可以轻松实现循环方法调用,即循环中方法的顺序调用。 让我们看看以下代码
for (int i=0; i<methods.Count; i++)
{
((MethodToInvoke)methods[i])();
}
例如,当您使用管道设计模式进行开发并需要一个接一个地调用多个方法时,该方法可能很有用。 您可能会说它与您使用 +=
运算符初始化多播委托时所做的事情非常相似。 这是真的。 但让我们找出差异。 多播委托必须具有 void
返回类型。 因此,如果您希望委托返回某些内容,则无法使用它。 但是,所提出的方法允许您轻松地做到这一点
delegate bool MethodToInvoke();
...
for (int i=0; i<methods.Count; i++)
{
if ( true != ((MethodToInvoke)methods[i])() )
break;
}
结论
在本文中,我简要描述了使用 .NET Framework 和 C# 语言(如反射和委托)的方法调用的一些方法。 使用这些功能可以让开发人员提高代码的灵活性、可读性和可管理性,有时还可以防止与 if
和 switch
语句相关的一些错误。 我可以带来更多使用所描述概念的代码示例。 但本文的目的只是为了说明在条件方法调用情况下使用委托和反射的常见想法。 我想本文已经很好地涵盖了这一目标。