有人告诉我 C# 中的多播委托(delegate)是不可变的。但下面的代码似乎证明它不是。
Action a = () => { };
Action b = a;
Console.WriteLine(ReferenceEquals(a, b));
它将显示 True 而不是 False。这是另一个例子:
public delegate void MyHandler();
public class Klass
{
public event MyHandler onCreate;
public void Create()
{
MyHandler handler = onCreate;
if (handler != null)
{
handler();
}
Console.WriteLine(ReferenceEquals(handler, onCreate));
}
}
该类将按如下方式调用:
Klass k = new Klass();
k.onCreate += () => { };
k.Create();
同上它会显示True,那么如果本地副本与原始副本引用相同,它怎么会是线程安全的呢?
最佳答案
How could it be thread safe if the local copy is the same reference as the orignal one?
我认为您可能误解了不变性的含义。维基百科是这样定义的:
In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created. This is in contrast to a mutable object, which can be modified after it is created.
从变量a
到b
的引用分配不会改变委托(delegate)的状态。因此,调用同一个委托(delegate)的多个线程保证调用同一个构造的委托(delegate)。请注意,这并不意味着该委托(delegate)引用的底层方法是线程安全的。请记住,C# 中的委托(delegate)是引用类型,它们是按值复制的,在这种情况下,值是 GC 堆中保存的对象的地址,而不是值本身的副本。有关委托(delegate)线程安全的更多信息,请参阅 Are C# delegates thread-safe?
关于c# - 为什么在 C# 中将委托(delegate)分配给本地副本线程安全,任何代码都可以证明这一点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29529796/