如何识别和调用标记有属性的方法

时间:2011-09-01 13:29:24

标签: c# custom-attributes

我想创建一个自定义属性以应用于类中的任何方法,然后从该类外部访问已使用该属性“标记”的类内的方法,以将标记方法调用为如果是代表。

e.g。

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

4 个答案:

答案 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 });
}

答案 1 :(得分:0)

我认为您的解决方案是使用您想要的属性查找方法。

答案 2 :(得分: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 *);

希望这有帮助。

答案 3 :(得分:0)

如其他地方所示,你可以做到

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

通过反射“GetMethods where has attribute”获取MethodInfo后,以下代码显示了如何基于MethodInfo构造委托。在此示例中,它是一些Action<>但它可以是不同的类型。这里"parameterType"是从外部提供的类型。生成的委托可以转换为您需要的类型。 "target"是此委托将被调用的实例。

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