【问题标题】:How to identify and call a method tagged with an attribute如何识别和调用带有属性标记的方法
【发布时间】:2011-09-01 13:29:23
【问题描述】:

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

例如

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 Class,将“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));         
            }
        }         
    }

【问题讨论】:

    标签: c# custom-attributes


    【解决方案1】:

    您可以使用反射和 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 });
    }
    

    【讨论】:

    • 我相信我的回答显示了实现相同目标的更紧凑和更有效的方式。
    • 对不起 Matías,但 WizzApp 的解决方案更符合我的喜好,虽然主要是因为我以前没有使用过 Linq,而且您的解决方案没有编译,我无法修复它,而 WizzApp 没有也无法编译,但我可以修复它。 :-S 感谢您的回答,不过我确实使用了您的“调用”代码。它有帮助!
    • 不用担心,您可以选择更适合您需求的答案
    【解决方案2】:

    要获得此方法,您必须做以下事情:

    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】:

    我认为您的解决方案是通过反射找到具有您想要的属性的方法。

    【讨论】:

      【解决方案4】:

      如其他地方所示,您可以这样做

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

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

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

      【讨论】:

        猜你喜欢
        • 2011-05-07
        • 2013-12-29
        • 2015-05-22
        • 1970-01-01
        • 2022-10-23
        • 2017-07-28
        • 2014-11-15
        • 2020-05-15
        • 1970-01-01
        相关资源
        最近更新 更多