委托在c#中不可变的目的是什么?

委托在c#中不可变的目的是什么?,c#,delegates,C#,Delegates,我在读一本书《C#2012》的章节,结合了代表们的观点,没有注意到吗?代表的目的是不变的 合并代表 到目前为止,您看到的所有代表都只有 它们的调用列表中只有一个方法。代表可以“组合” 通过使用加法运算符。操作的结果是 创建一个新委托,其中调用列表是 两个操作数的调用列表副本的串联 代表们。例如,以下代码创建三个委托。 第三个委托是由前两个委托的组合创建的 虽然“组合代表”一词可能给人的印象是 操作数委托已修改,但根本不更改。在里面 事实上,委托是不可变的。创建委托对象后,它将 无法更改。图15-

我在读一本书《C#2012》的章节,结合了代表们的观点,没有注意到吗?代表的目的是不变的

合并代表 到目前为止,您看到的所有代表都只有 它们的调用列表中只有一个方法。代表可以“组合” 通过使用加法运算符。操作的结果是 创建一个新委托,其中调用列表是 两个操作数的调用列表副本的串联 代表们。例如,以下代码创建三个委托。 第三个委托是由前两个委托的组合创建的

虽然“组合代表”一词可能给人的印象是 操作数委托已修改,但根本不更改。在里面 事实上,委托是不可变的。创建委托对象后,它将 无法更改。图15-6说明了试验结果 前面的代码。请注意,操作数委托保持不变


委托是指向方法的指针,可以是具体的,也可以是匿名的(甚至匿名方法都是用编译器生成的标识符编译的)

指向某个具体事物的事物是可变的,这是合理的吗?我不这么认为。每个实例表示指向某个方法的指针。你想用别的方法吗?创建一个新指针。也就是说,实例化一个新委托


另一方面,添加两个或更多代理会产生此结果,因为。也就是说,委托可以是添加的一部分,但在内部
+
的重载正在创建一个具有调用列表的新委托。

线程安全和速度是这里主要关注的问题。委托更新不是原子更新,它需要更新6个字段和一个列表。使其原子化以防止损坏需要一个锁,这对于这样一个很少需要线程安全的基本操作来说太昂贵了

通过使其不可变,委托对象不会损坏,因为它总是在没有人引用的对象上设置字段。重新分配委托对象引用是原子的,这是基本的.NET内存模型保证。所以不再需要锁了。取舍是内存使用效率较低,这是一个很小的惩罚


请记住,线程安全委托更新也不会自动使代码线程安全。测试和启动代码需要复制引用以避免NRE,您可以对已取消订阅的方法进行回调。

委托实际上是方法指针。您建议对这样一位代表做什么?修改底层方法?@YuvalItzchakov嗯,可能OP认为它们是可变的,所以添加两个委托会重用其中一个委托的实例,并将一个委托添加到调用列表中。。。谁知道呢
MyDel delA = myInstObj.MyM1;
MyDel delB = SClass.OtherM2;
MyDel delC = delA + delB; // Has combined invocation list