C#如何获取Actions关联对象并判断它是否仍然存在

时间:2014-07-10 21:27:32

标签: c# reflection delegates null

我想获取与Action委托相关联的对象,并确定它是否为null。我该怎么做?没有反思可能吗?

1 个答案:

答案 0 :(得分:1)

Action是委托类型,因此它的基类MulticastDelegate继承自Delegate,它公开了Method和Target属性。您可能对Target感兴趣,因为它"获取当前委托调用实例方法的类实例。" 它的值是"当前委托调用实例方法的对象,如果委托表示实例方法;如果委托代表静态方法,则返回null。"

如果您将Action对象转换为MulticastDelegate(或Delegate),则可以在此代码段中验证:

public class A
{
    public void foo()
    {
        Console.WriteLine("A.foo()");
    }

    public void foo2()
    {
        Console.WriteLine("A.foo2()");
    }

    public static void bar()
    {
        Console.WriteLine("A.bar()");
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        Action action = a.foo;
        action += a.foo2; 
        MulticastDelegate d = (MulticastDelegate)action;
        Debug.Assert(object.ReferenceEquals(d.Target, a)); // passes
        action();
        action = A.bar;
        d = (MulticastDelegate)action;
        Debug.Assert(object.ReferenceEquals(d.Target, null)); // passes
        action();
    }
}

输出:

A.foo()
A.foo2()
A.bar()

请注意Target返回添加到调用列表的最后一个对象的实例:

public class B
{
    public void foo()
    {
        Console.WriteLine("B.foo()");
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = new B();
        Action action = a.foo;
        action += a.foo2;
        action += b.foo;
        MulticastDelegate d = (MulticastDelegate)action;
        Debug.Assert(object.ReferenceEquals(d.Target, b)); // passes
        action();
        action = A.bar;
        d = (MulticastDelegate)action;
        Debug.Assert(object.ReferenceEquals(d.Target, null)); // passes
        action();
    }
}

输出:

A.foo()
A.foo2()
B.foo()
A.bar()