Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果委托是不可变的,为什么我可以做x+;=Y_C#_Delegates_Immutability - Fatal编程技术网

C# 如果委托是不可变的,为什么我可以做x+;=Y

C# 如果委托是不可变的,为什么我可以做x+;=Y,c#,delegates,immutability,C#,Delegates,Immutability,深入阅读C#,第二版,第2.1.2节关于合并和删除代理的内容 小节标题声明“委托是不可变的”,并且“关于委托的任何内容都不能更改”。不过,在下一段中,它将讨论使用如下结构 x += y; 其中x和y是兼容委托类型的变量 我不是刚换了x?或者,当我这样做(即,立即)时,x被处理时,不变性部分会处理吗?这类似于: string x = "x"; string y = "y"; x += y; 字符串也是不可变的。上面的代码没有更改字符串对象-它将x设置为不同的值 您需要区分变量和对象。如果一个

深入阅读C#,第二版,第2.1.2节关于合并和删除代理的内容

小节标题声明“委托是不可变的”,并且“关于委托的任何内容都不能更改”。不过,在下一段中,它将讨论使用如下结构

x += y;
其中
x
y
是兼容委托类型的变量

我不是刚换了
x
?或者,当我这样做(即,立即)时,
x
被处理时,不变性部分会处理吗?

这类似于:

string x = "x";
string y = "y";

x += y;
字符串也是不可变的。上面的代码没有更改字符串对象-它将
x
设置为不同的值

您需要区分变量和对象。如果一个类型是不可变的,这意味着您不能在构造该类型的实例后更改该实例中的数据。不过,您可以为该类型的变量指定不同的值

如果您了解这是如何处理字符串的,那么委托也是如此。+=实际调用了Delegate.Combine,因此:

x += y;
相当于:

x = Delegate.Combine(x, y);

它不会更改以前提到的代理对象的任何内容-它只是创建一个新的代理对象,并分配一个引用该新代理的值。

您已经更改了
x
,但没有更改其值(即它所持有的代理)

这与:

int num = 4;
num += 2;

那么,写《C#Depth》的人的回答呢?尼尔:是的,被乔恩·斯基特(Jon Skeet)回答是非常罕见的事,所以这是一个值得注意的巧合。@stakx:没错,是的。因此,如果对同一个委托有两个引用:
x=y然后执行
x+=z;y、 调用()
那么对
y.Invoke()
的调用将不会调用
z
@stakx:Yes所引用的委托(回答不再存在的问题),这就是为什么我们应该在调用副本之前复制一个事件的委托并检查副本是否为
null
,而不是在调用之前检查原始委托是否为
null
,以避免竞争条件。@Jon:当然!我知道堆栈溢出不是SAAS(Skeet即服务)!;)