代表的目的是什么,在c#中是不可变的?

时间:2016-03-13 09:59:11

标签: c# delegates

我正在阅读C#2012中的一本书,在“结合代表”一节中没有注意到这一点?代表的目的是不可改变的。

  

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

MyDel delA = myInstObj.MyM1;
MyDel delB = SClass.OtherM2;
MyDel delC = delA + delB; // Has combined invocation list
  

虽然组合代表这一术语可能给人的印象是   操作数委托被修改,它们根本没有改变。在   事实上,代表是不可改变的。创建委托对象后,它   无法改变。图15-6说明了结果   前面的代码。请注意,操作数委托保持不变。

enter image description here

2 个答案:

答案 0 :(得分:7)

线程安全性和速度是这里的主要关注点。委托更新不是原子的,它需要更新6个字段和列表。使其成为原子以便它不会被破坏需要一个锁,这对于很少需要的线程安全的基本操作来说太昂贵了。

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

请记住,线程安全的委托更新不会自动使您的代码也是线程安全的。 test-and-fire代码需要复制引用以避免NRE,并且您可以回调已经取消订阅的方法。

答案 1 :(得分:2)

委托是指向某个方法的指针,无论是具体的还是匿名的(,甚至匿名方法都是使用一些编译器生成的标识符编译的。)

指出某些具体事情是可变的是合理的吗?我不这么认为。每个实例代表一个指向某个方法的指针。你想指出其他一些方法吗?创建一个新指针。也就是说,您实例化一个新的委托。

另一方面,添加两个或更多代表的结果是+ operator can be overloaded。也就是说,委托可以成为添加的一部分,但内部+的重载正在创建一个带有调用列表的新委托。