簡體   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