2009-08-18 21 views

回答

11

是你可以使用的System.Reflection


CallStaticMethod("MainApplication.Test", "Test1"); 

public static void CallStaticMethod(string typeName, string methodName) 
{ 
    var type = Type.GetType(typeName); 

    if (type != null) 
    { 
     var method = type.GetMethod(methodName); 

     if (method != null) 
     { 
      method.Invoke(null, null); 
     } 
    } 
} 

public static class Test 
{ 
    public static void Test1() 
    { 
     Console.WriteLine("Test invoked"); 
    } 
} 
+0

好例子;我剛剛發佈幾乎完全相同的代碼(只是區別在於我的版本CallStaticMethod只接收一個字符串,並在內部將它切斷以與方法名稱分離類型,並且它還返回方法的結果)。 – 2009-08-18 10:24:58

1

你可以嘗試這樣的:

typeof (MyClass).GetMethod (MyClass.GetData) // Assuming get data is the string name. 

,將返回給你MethodInfo類。從那裏,你可以使用Invoke方法(使用正確的參數)。

+2

這個示例有很多問題,主要的一點是它不會編譯,因爲GetMethod接受一個'string'參數。還有對GetType的不必要的調用; 'typeof(MyClass)'返回一個'Type'對象。在該對象上調用'GetType'將返回描述'Type'而不是'MyClass'的'Type'對象,並且不會找到'GetData'方法。 – 2009-08-18 10:28:39

+0

的意圖是正確的 - 代碼不是 – Gishu 2009-08-18 10:32:01

+0

道歉,是第一次與第二次交替的結果...我的內置C#編譯器失敗(; – Kieron 2009-08-18 10:41:39

1

答案在於反思。 您可以使用反射來獲取特定類型的MethodInfo。 (你必須知道它的類型),然後你可以調用它。

但是,你確定沒有更好的解決方案來解決你的問題嗎?爲什麼它作爲一個字符串傳遞?

2

是的您可以使用反射來查找方法並調用適當的參數。

2

Reflection API

class Test 
{ 
    public void Print(int n) 
    { 
     Console.WriteLine(n); 
    } 
} 
class MainA 
{ 
    static void Main() 
    { 
     Type t = typeof(Test); 
     Object obj = new Test(); 
     System.Reflection.MethodInfo m = t.GetMethod("Print"); 
     m.Invoke(obj,new object[]{11}); 
    } 
} 
1

反思有你需要的基本工具,但是你仍然需要解析自己的字符串(拆呢在點上,並一直反映到必要的MethodInfo)。但是你應該注意到,這種操作的執行速度比直接方法調用慢幾倍(如果不是千次或更多)。可以做幾次,但是如果你打算這麼做的話,你應該考慮重構你的代碼,這樣做是沒有必要的。

如果你真的不能避免這種情況(在大多數情況下你可以),你至少可以通過緩存你在一些字典中找到的MethodInfo對象來加速它。這樣你就不必每次都反映了。

此外,如果你不知道他們,我會建議查找delegates。有機會,這是你的問題的答案。它幾乎和直接方法調用一樣快。

0

是的。唯一的問題是你需要提供類的命名空間。

哈希似乎已經釘了很多。自從我把打字出來..這裏是我的版本的麻煩(溫度是命名空間,用戶是類名並存是在它一個公共靜態方法。)

private static object ExecuteStaticMethod(string method_full_path, object[] args) 
     { 
     var tokens = method_full_path.Split('.'); 
     string class_full_name = String.Format("{0}.{1}", tokens[0], tokens[1]); 
     var class_blueprint = Assembly.GetExecutingAssembly().GetType(class_full_name); 
     var handle_to_method = class_blueprint.GetMethod(tokens[2], BindingFlags.Default | BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public); 
     return handle_to_method.Invoke(null, args); 

     } 

     public static void Main(string[] args) 
     { 
     Console.WriteLine(ExecuteStaticMethod("temp.User.Exists", new object[] {"Gishu"})); // prints false 
     User.Create("Gishu"); 
     Console.WriteLine(ExecuteStaticMethod("temp.User.Exists", new object[] { "Gishu" })); // prints true 
     } 
1

之前下降反射的路徑,這就是你所要做的事情被稱爲,確保沒有其他更好的實現方式。首先檢查委託,因爲它們可以調用在運行時設置的方法。

所以在這裏你去反思:

public void MyFunction() 
{ 
    string dotSeparatedParams = "Myclass.Method"; 
    string[] arrayParams = dotSeparatedParams.Split('.'); 
    // since the class was defined in the string, start with loading it 
    Type classType = Type.GetType(arrayParams[0]); 
    if(classType == null) 
     throw new Exception(); 
    // load the reference to the method 
    MethodInfo mi = classType.GetMethod(arrayParams[1]); 
    if (mi == null) 
     throw new Exception(); 
    // call the method 
    mi.Invoke(null, null); 
} 

的幾個注意事項:

  • 在這個例子中,你的方法必須是靜態的。原因是我們沒有實例化'MyClass'。可以這樣做,但它需要一個沒有參數的默認構造函數。看看.GetConstructor。但通常情況下,創建班級以動態調用方法並不可取。
  • 在我的例子中,靜態方法沒有使用任何參數。如果是這樣,那麼將mi.Invoke(...)的第二個參數替換爲一個對象數組:new object [2] {232,「string」}
  • 您可以將您想要的對象改爲調用該方法。你需要一個MyFunction的參數來接受一個'MyClass'類型的對象,並且你將該對象傳遞給mi.Invoke()調用。
相關問題