繁体   English   中英

使用C#中的名称调用方法

[英]Call methods using names in C#

我的应用程序中有许多“作业”,每个作业都有一个需要调用的方法列表以及其参数。 本质上,包含以下对象的列表称为:

string Name;
List<object> Parameters;

因此,基本上,当作业运行时,我想通过此列表进行枚举,并调用相关方法。 例如,如果我有如下方法:

TestMethod(string param1, int param2)

我的方法对象是这样的:

Name = TestMethod
Parameters = "astring", 3

是否有可能做到这一点? 我想反射将是关键。

当然,您可以这样做:

public class Test
{
    public void Hello(string s) { Console.WriteLine("hello " + s); }
}

...

{
     Test t = new Test();
     typeof(Test).GetMethod("Hello").Invoke(t, new[] { "world" }); 

     // alternative if you don't know the type of the object:
     t.GetType().GetMethod("Hello").Invoke(t, new[] { "world" }); 
}

Invoke()的第二个参数是一个Object数组,其中包含所有要传递给您的方法的参数。

假设所有方法都属于同一类,则可以使用该类的方法,例如:

public void InvokeMethod(string methodName, List<object> args)
{
    GetType().GetMethod(methodName).Invoke(this, args.ToArray());
}

如果您使用的是.NET Framework 4,请查看dynamic ,否则查看GetMethod ,然后Invoke MethodInfo Invoke

Nu抢救! PM> Install-Package dnpextensions

在项目中拥有该程序包后,所有对象现在都应具有.InvokeMethod()扩展名,该扩展名将方法名作为字符串和任意数量的参数。

从技术上讲,这确实使用了“魔术字符串”作为方法名称,因此,如果您想对方法字典进行强类型输入,则可以输入MethodInfo类型的键并按如下方式获取它们:

MethodInfo[] methodInfos = typeof(MyClass).GetMethods();

然后您可以执行类似的操作...

var methods = new Dictionary<MethodInfo, Object[]>();
foreach (var item in methods)
   item.key.Invoke(null, item.value);  
   // 'null' may need to be an instance of the object that
   // you are calling methods on if these are not static methods.

或者,您可以使用我前面提到的dnpextensions对上述块进行一些更改。

使用MethodBase.Invoke() 应该使用System.Reflection降级到.NET 2.0。

如果您不得不求助于反思,那么可能会有更好的方法来完成任务。 它可能需要更多的体系结构,但是是可行的。

请记住,拥有更多代码不是一件坏事-尤其是当它补充了代码的可读性和可管理性时。 对于大多数人来说,反射是很难理解的,并且会损失大部分编译时类型的安全性。 在您的示例中,您可能只打算使用switch语句和打算调用的每种方法使用不同的对象。 例如

// Have some object hold the type of method it plans on calling.
enum methodNames
{
   Method1,
   Method2
}

...
class someObject
{
   internal methodNames methodName {get; set;}
   internal object[] myParams;
}
...

//  Execute your object based on the enumeration value it references.
switch(someObject1.methodName)
{
   case Method1:
      Test.Method1(Int32.Parse(someObject1.myParams[0].ToString),someObject1.myParams[1].ToString());
      break;
   ...
}

如果您知道只有几种独特的方法可以调用,为什么不提前设置自己呢?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM