反射属性方法

时间:2014-04-17 08:38:26

标签: c#

我有一个asbtract类,我有一些从它开始的类。我有一个名为PluginEventAttribute的属性,其工作原理如下:

[PluginEventAttribute(PluginEvent.Load)]
public void OnLoad()
{
    Log("Test Plugin loaded!");
}

我希望我的代码检查是否使用该属性的方法,如果是,请使用自定义参数调用它。我怎么能用C#winforms做到这一点?

2 个答案:

答案 0 :(得分:1)

如果它具有所述属性,您只需枚举实例方法并调用该方法。这是一个有效的例子(我希望我的意图正确):

using System;
using System.Reflection;

class Program
{
    class MyAttr : Attribute { }

    abstract class Base { };

    class Derived : Base
    {
        [MyAttr]
        public void foo() { Console.WriteLine("foo"); }
        public void bar() { Console.WriteLine("bar"); }
    }

    static void Main()
    {
        Base someInstance = new Derived();

        foreach (var m in someInstance.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance))
        {
            if (m.GetCustomAttribute(typeof(MyAttr)) != null)
            {
                m.Invoke(someInstance, null); // prints "foo"
            }
        }

        Console.ReadLine();
    }
}

您可以将对null的调用中的Invoke参数更改为您希望传递给函数的参数数组。该数组的内容必须匹配函数签名。

答案 1 :(得分:0)

这与WinForms无关。这完全是关于CLR运行时及其类型系统。

我不知道你怎么能“做到这一点”。

只有当您拥有描述该方法的MethodInfo对象(methodinfo.GetCustomAttributes()

时,才能检查方法M是否具有属性A.

您可以通过多种方式获取MethodInfo,但最简单也是最明显的是获取Type对象并询问其方法(type.GetMethod()/type.GetMethods())。

您也可以通过多种方式获得Type个对象。如果您手头有任何对象,则可以调用其GetType()方法。或者,您可以询问有关其定义的类型的Assembly对象(描述DLL或EXE)。 (..)

所以,如果你有一个人已经创建的foo对象:

call foo.GetType()
loop over type.GetMethods()
    call method.GetCustomAttributes(typeof(YourAttribute))
    check if it was found

现在,如果您发现它已被发现,那么您最终会得到一个与该属性的方法匹配的MethodInfo。剩下的唯一事情是用methodinfo.Invoke调用该方法并将其传递给参数 foo对象

如果您没有要扫描方法的foo对象,情况会变得棘手。您必须获得整个程序集,扫描所有类型,扫描所有方法。最后再次匹配MethodInfo。但是你没有任何对象可以调用找到的方法。要么该方法需要static(所以没有目标对象就可以调用),或者你也需要以某种方式得到匹配的对象。