2008-09-16 83 views
1

我有一個應用於類的自定義處理程序(使用Entlib 4中的策略注入應用程序塊),我想知道當調用Invoke時輸入方法是否屬性。以下是我的處理程序的樣子。什麼是最好的方式來判斷一個方法是否是策略注入中的一個屬性?

[ConfigurationElementType(typeof(MyCustomHandlerData))] 
public class MyCustomHandler : ICallHandler 
{ 
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) 
    { 
     if (input.MethodBase.IsPublic && (input.MethodBase.Name.Contains("get_") || input.MethodBase.Name.Contains("set_"))) 
     { 
      Console.WriteLine("MyCustomHandler Invoke called with input of {0}", input.MethodBase.Name); 
     } 
     return getNext().Invoke(input, getNext); 
    } 

    public int Order { get; set; } 
} 

正如你從我的代碼示例中看到的,到目前爲止我想到的最好方法是解析方法名稱。沒有更好的方法來做到這一點?

回答

2

您還可以檢查IsSpecialName是真的。這將在屬性(除其他事項外)

在IL級別是真實的方法是暴露如下(使用Environment.ExitCode爲例):

.method public hidebysig specialname static int32 get_ExitCode() cil managed 
.method public hidebysig specialname static void set_ExitCode(int32 'value') cil managed 

如果你想獲得幻想你可以提取所述屬性存在,但說實話

if (m.IsSpecialName && (m.Attributes & MethodAttributes.HideBySig) != 0)) 

以及具有的get_或SET_開始,那麼你應該甚至用難聽的名字的人是好名後確認(僞造的hidebysig是很容易的,僞造的IsSpecialName會非常棘手)

雖然沒有保證。有人可以用一個set_Foo方法發出一個類,該方法看起來就像一個真實的方法,但實際上不是一個只讀屬性集。 除非您檢查屬性CanRead/CanWrite以及。

儘管您不期望有意的規避行爲,但這讓我感到瘋狂。 MethodInfo上的一個簡單的實用程序/擴展方法,它不會太難,包括IsSpecialName幾乎肯定會覆蓋您的所有需求。

0

您可以檢查IsSpecialName屬性;對於屬性獲取者和制定者來說,這是事實。但是,其他特殊方法也是如此,例如運算符重載。

0

你們之中有人提到過使用MethodBase類型的「IsSpecialName」屬性。儘管確實會爲屬性「gets」或「sets」返回true,但它也會爲運算符重載(如add_EventName或remove_EventName)返回true。因此,您需要檢查MethodBase實例的其他屬性以確定其屬性訪問器是否屬於它。不幸的是,如果你所擁有的只是對MethodBase實例的引用(我認爲這是在Unity框架中攔截行爲的情況下),那麼確定它是否屬性設置器或獲取器並不是真正的「乾淨」方式。我發現最好的方法如下:

C#:

bool IsPropertySetter(MethodBase methodBase){ 
    return methodBase.IsSpecialName && methodBase.Name.StartsWith("set_"); 
} 

bool IsPropertyGetter(MethodBase methodBase){ 
    return methodBase.IsSpecialName && methodBase.Name.StartsWith("get_"); 
} 

VB:

Private Function IsPropertySetter(methodBase As MethodBase) As Boolean 

     Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("set_") 

End Function 

Private Function IsPropertyGetter(methodBase As MethodBase) As Boolean 

     Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("get_") 

End Function 
0

這是一個有點晚了,但其他人會讀這一點。除了IsSpecialName和檢查set_前綴(運算符還有op_,event subscr./remov。有add_,remove_)您可以檢查方法是否與以下任何屬性方法匹配:

bool isProperty = method.ReflectedType.GetProperties().FirstOrDefault(p => 
     p.GetGetMethod().GetHashCode() == method.GetHashCode() 
     || p.GetSetMethod().GetHashCode() == method.GetHashCode())!=null; 
相關問題