2011-06-24 47 views
16

我的應用程序中有許多'作業',其中每個作業都有一個需要調用的方法列表及其參數。主要包含以下對象的列表被稱爲:在C#中使用名稱的調用方法

string Name; 
List<object> Parameters; 

因此,基本上,當一個作業運行我想通過這個列表枚舉,並調用相關的方法。舉例來說,如果我有類似下面的方法:

TestMethod(string param1, int param2) 

我的方法的對象會是這樣的:

Name = TestMethod 
Parameters = "astring", 3 

是否有可能做到這一點?我想在這裏反思將是關鍵。

回答

35

當然,你可以像這樣做:

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" }); 
} 

調用的第二個參數()是一個包含所有參數Object數組傳遞到您的方法。

假設所有屬於同一個類中的方法,你可以有該類類似的方法:

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

神奇,正是我在找的。謝謝 :) – Chris

1

如果您使用的是.NET Framework 4,請看dynamic,否則GetMethod,然後撥打電話InvokeMethodInfo

+0

我不難過,我在3.5 – Chris

-1

如果您使用不得不求助於反思,那麼可能有更好的方法來完成您的任務。它可能需要更多的架構,但它是可行的。請記住,擁有更多代碼並不是一件壞事 - 尤其是當它支持代碼的可讀性和可管理性時。大多數情況下,反射很難理解,並且會丟失大部分編譯時類型安全性。在你的例子中,你可能只是爲了你打算調用的每個方法而放棄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; 
    ... 
} 

如果你知道你只有一組不同的方法調用,爲什麼不直接設置自己呢?

1

NuGet救援! 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上述區塊的一些變化。