2011-09-01 22 views
3

我想創建一個自定義屬性以應用於類中的任何方法,然後從該類外部訪問該類中已經'使用該屬性標記'來調用標記的方法,就好像它是一個委託。如何識別和調用帶有屬性標記的方法

例如

public delegate string MethodCall(string args); 

public class MethodAttribute : System.Attribute 
{ 
    public MethodCall callback; 
    ... 
} 

class TypeWithCustomAttributesApplied { 

    [Method] 
    public string DelegateMethod(string args) { 
     ... 
    } 
} 

然後

void callMethods(string args) { 
    TypeWithCustomAttributesApplied myObj = new TypeWithCustomAttributesApplied(); 
    DelegateMethod method = MyCustomerHelper.GetMarkedMethod(myObj) 
    method(args); 
} 

或也許

void callMethods(string args) { 
    TypeWithCustomAttributesApplied myObj = new TypeWithCustomAttributesApplied(); 
    MethodAttribute methodAtrib = MyCustomerHelper.GetMarkedMethod(myObj) 
    methodAtrib.callback(args); 
} 

我最終試圖實現的是一種自定義屬性,我可以用它來標記任意類中的Ajax入口點,然後用一個Helper類將'Ajax Enabled'控件傳遞給幫助程序,以識別哪個方法在控件中調用,並從客戶端傳遞ajax數據。我對代表人不太瞭解,但我通常瞭解如何應用自定義屬性,但不知道如何「捕捉」我正在'標記'的方法

我大概可以用其他方式管理我的任務,但我正在努力研究屬性,所以我想先讓這個方法工作。


我的最終解決方案:

public void CheckAjax(object anObject, string args) 
    { 
     MethodInfo[] methods = anObject.GetType().GetMethods(); 
     foreach (MethodInfo method in methods) 
     { 
      object[] attributes = method.GetCustomAttributes(true); 

      bool containsAttribute = (from attribute in attributes 
             where attribute is AjaxableAttribute 
              select attribute).Count() > 0; 

      if (containsAttribute) 
      { 
       string result_method = (string)method.Invoke(anObject, new object[] { args }); 
       Log.Write(string.Format("The Result from the method call was {0} ", result_method));   
      } 
     }   
    } 

回答

0

你必須做的就是這個方法什麼是以下幾點:

MethodInfo[] methods = typeof(TypeWithCustomAttributesApplied).GetMethods(); 
foreach (MethodInfo method in methods) 
{ 
    object[] attributes = method.GetCustomeAttributes(true); 

    bool containsAttribute = (from attribute in attributes 
           where attribute is MethodAttribute 
            select attribute).Count() > 0; 

    if (containsAttribute) 
     // add attribute to list to return later 
} 

返回方法之後,你可以調用的方法與

method.Invoke(/* parameters *); 

希望這會有所幫助。

+0

我用我的解決方案的大部分代碼,感謝您的幫助! – Nnoel

+0

不客氣,很高興我能提供幫助。 –

0

我覺得你該解決方案將是反射來找到你想要的屬性的方法。

2

您可以使用反射和LINQ:

IEnumerable<MethodInfo> methods = myObj.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public).Where(method => method.GetCustomAttributes(typeof(MethodAttribute), true).Length == 1).ToList(); 

string args = "some args"; 

foreach(MehtodInfo method in methods) 
{ 
     method.Invoke(myObj, new object[] { args }); 
} 
+0

打我給它;-) –

+0

我相信我的回答顯示了實現相同目標的更緊湊,更高效的方式。 –

+0

對不起馬蒂亞斯,但WizzApp的解決方案更符合我的喜好,儘管大部分原因是我之前沒有使用過Linq,並且您的解決方案沒有編譯,我無法修復它,而WizzApp的也沒有編譯,但我可以_修理它。 :-S謝謝答案,儘管我確實使用了你的'Invoke'代碼。它幫助! – Nnoel

0

如圖別的地方,你可以做

from m in type.GetMethods() 
where m.GetCustomAttributes().OfType<YourAttribute>().Any() 
select m 

一旦你得到你通過反射「其中的getMethods具有屬性」的MethodInfo下面的代碼展示瞭如何構建基於一個MethodInfo的委託。在這個例子中,它有一些Action<>,但它可能是一個不同的類型。這裏"parameterType"是從外部提供的一種類型。結果委託可以轉換爲您需要的類型。 "target"是這個委託將被調用的實例。

var fittingDelegateType = typeof(Action<>).MakeGenericType(parameterType); 
var @delegate = Delegate.CreateDelegate(fittingDelegateType, target, info); 
相關問題