gpt4 book ai didi

c# - 为什么在分配方法组时不引发 "forwarded"事件,但在分配委托(delegate)时引发?

转载 作者:行者123 更新时间:2023-11-30 15:24:51 26 4
gpt4 key购买 nike

给定以下代码:

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 但它并没有这样做这里。所以显然它知道它不应该在这里这样做。

最佳答案

当您将方法组分配给这样的事件时:

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

您实际上从 SignalExtensions.SafeInvoke 方法创建了一个委托(delegate),它作为参数接受您的 this.AnotherEvent 委托(delegate)对象。由于它最初是 null,因此您创建了一个带有 null 参数的委托(delegate)。这个 null 值当然永远不会改变,因为委托(delegate)是不可变的。

如果你想转发一个事件你应该这样做:

public class EventForwarder
{
private readonly RootEventSource rootEventSource;

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

public event Signal AnotherEvent
{
add { this.rootEventSource.RootEvent += value; }
remove { this.rootEventSource.RootEvent -= value; }
}
}

关于c# - 为什么在分配方法组时不引发 "forwarded"事件,但在分配委托(delegate)时引发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32227948/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com