2011-04-05 79 views
2

假設我通過以下方式獲得的MethodInfo:如何使用反射來重構按名稱獲取方法?

Assembly assembly = Assembly.Load(assemblyName); 
Type type = assembly.GetType(nameSpaceName+"."+className); 
MethodInfo mi = type.GetMethod("myMethod", bf); // bf are the binding flags. 

但後來我決定改變myMethod情況/名稱。

有沒有辦法要麼:

  1. 重構,使其變爲字符串中的名稱。
  2. 更改反射調用,以便它不使用方法的名稱作爲字符串獲取該方法?

這樣做的原因是我可以測試我需要使用反射的代碼,但我寧願不要求沒有人更改代碼中的方法名稱。

+3

一句話:小心!這一切都將取決於你如何以及爲什麼使用反射。「myMethod」這個名字有什麼特別之處?類沒有實現一個接口,或類似的東西? – 2011-04-05 17:01:33

+0

嗯......我想myMethod是特殊的,我知道另一種方法稱之爲myMethodCaller。所以當我測試時,我希望看到myMethod的調用者爲myMethodCaller。我想我可以期望不改變這兩種方法......但我不喜歡那樣。 – user420667 2011-04-05 17:17:57

+0

在你的場景中有可能讓動態加載的程序集中的類型實現一個接口嗎?這樣你就不必通過反射調用方法了(但是仍然可以插入體系結構)。 – RQDQ 2011-04-05 17:20:59

回答

2

如果您使用Visual Studio做重構,還有就是搜索的名稱文字字符串和意見,並改變那些過於選項。但是,強烈建議在使用該選項時使用預覽,以驗證您只是在更改預期的部分。

當然,你可以使用一個恆定像internal const string methodName = "methodName";使您只有文字串一次。重構方法名稱時,可以手動更改一個字符串文字。您還可以更輕鬆地重命名methodName

+0

感謝您提請我注意。從來沒有仔細看過重構對話框。 – user420667 2011-04-05 17:53:50

+0

如果方法名稱與註釋中常用的字符串匹配,此方法會變得非常難看。有一個更好的方法。 – GregC 2011-04-06 05:16:09

+1

@GregC:這正是我告訴他使用預覽的原因。否則它會變得非常混亂。 – Gabe 2011-04-06 05:35:26

1

您可以使用自定義屬性,並使用此屬性修飾您的方法。然後,不要通過名稱獲取方法,您可以通過屬性中定義的ID來獲取它。這樣,方法名稱就可以隨時改變,只需要一個想法即可。

[AttributeUsage(AttributeTargets.Method)] 
public class CustomMethodAttribute : Attribute 
{ 
    public string ID { get; set; } 
} 

用法:

[CustomMethodAttribute(ID = "UniqueIDHere")] 
public void Test() 
{ 

} 
+0

嗯......有趣的解決方案。我想你必須結合使用MethodInfo.GetCustomAttributes(CustomMethodAttribute,false/true)。還是有另一種方式? – user420667 2011-04-05 19:12:43

+0

是的 - 只是另一種選擇。爲您提供對命名約定的更多控制,並且您可以自定義GhostDoc以在添加XML註釋時添加屬性。 – BrandonZeider 2011-04-05 19:19:55

1

您是否對所討論的類型有具體的參考?

即使你沒有它明確,可以使該方法一般。

public void TestMethod<TargetType>(object o) 
{ 
    if (typeof(TargetType).IsAssignableFrom(o.GetType())) { 
     TargetType strongType = o as TargetType; 
     strongType.myMethod(); 
    } 
} 

其實,你可以做到這一點沒有反映在所有:

public void TestMethod<TargetType>(object o) 
{ 
    if (o is TargetType) { 
     TargetType strongType = o as TargetType; 
     strongType.myMethod(); 
    } 
} 
+0

是的,謝謝。我知道我可以直接調用它,但這不是我想要做的。 – user420667 2011-04-05 17:53:12

+0

@ user420667,如果你必須使用動態調用,那麼顯然你不能在編譯時通過名字綁定到方法。在這種情況下,我只是使用一個「const string」作爲方法名稱,並在你動態調用的地方引用這個const。 – harpo 2011-04-05 17:56:17

0

的方法和使用表達式樹的屬性嘗試。 您可以從中獲取與反射相關的信息,節省編譯時間檢查並啓用自動重構。 我相信你也可以獲得與程序集相關的信息和名稱空間名稱。 只需編寫幾個可從表達式樹中檢索這些信息的幫助函數。

你可以找到幾個輔助函數here 他們允許寫這樣的代碼:

FirePropertyChanged(() => PropertyName); 

這是一樣的

FirePropertyChanged("PropertyName");