为什么要转发""分配方法组但在分配代理时未引发事件?

时间:2015-08-26 13:26:03

标签: c#

给出以下代码:

public delegate void Signal();

public static class SignalExtensions
{
    public static void SafeInvoke(this Signal signal)
    {
        Signal copy = signal;
        if (copy != null)
        {
            copy();
        }
    }
}

public class RootEventSource
{
    public event Signal RootEvent;

    public void Raise()
    {
        this.RootEvent.SafeInvoke();
    }
}

public class EventForwarder
{
    private readonly RootEventSource rootEventSource;

    public EventForwarder(RootEventSource rootEventSource)
    {
        this.rootEventSource = rootEventSource;

        // this is the critical part
        this.rootEventSource.RootEvent 
             += () => this.AnotherEvent.SafeInvoke();
    }

    public event Signal AnotherEvent;

    // just an example of another method which is using the root event source
    public override string ToString()
    {
        return this.rootEventSource.ToString();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var rootEventSource = new RootEventSource();
        var eventForwarder = new EventForwarder(rootEventSource);

        eventForwarder.AnotherEvent += HandleAnotherEvent;

        rootEventSource.Raise();

        Console.WriteLine("done");
        Console.ReadKey();
    }

    private static void HandleAnotherEvent()
    {
        Console.WriteLine("received AnotherEvent");
    }
}

这导致输出:

received AnotherEvent
done

现在我对EventForwarder的实现稍作修改,以使用方法组转发事件:

public EventForwarder(RootEventSource rootEventSource)
{
    this.rootEventSource = rootEventSource;
    this.rootEventSource.RootEvent += this.AnotherEvent.SafeInvoke;
}

输出变为:

done

因此AnotherEvent 未被提升

到现在为止,我会考虑这两行:

this.rootEventSource.RootEvent += this.AnotherEvent.SafeInvoke;
this.rootEventSource.RootEvent += () => this.AnotherEvent.SafeInvoke();

等同于。似乎他们不是。

那有什么区别?加上为什么没有提出这个事件?

PS:虽然通常R#建议将() => this.AnotherEvent.SafeInvoke();替换为this.AnotherEvent.SafeInvoke,但此处并未执行此操作。显然它知道它不应该在这里做。

1 个答案:

答案 0 :(得分:4)

将方法组分配给此类事件时:

this.rootEventSource.RootEvent += this.AnotherEvent.SafeInvoke;

您实际上是从方法SignalExtensions.SafeInvoke创建一个委托,该委托作为参数获取您的this.AnotherEvent委托对象。由于它最初为null,因此您可以使用null参数创建委托。 <{1}}值当然永远不会改变,因为委托是不可变的。

如果您想转发活动,您应该这样做:

null