问题描述
我正在读一本C# 2012 中的C# 结合代表点,没有注意到这一点?代表的目的是不可变的.
合并代表到目前为止你见过的所有代表都只有调用列表中的单个方法.代表可以组合"通过使用加法运算符.操作的结果是创建一个新的委托,其调用列表是两个操作数的调用列表副本的串联代表.例如,以下代码创建三个委托.第三个委托是由前两个委托创建的.
MyDel delA = myInstObj.MyM1;MyDel delB = SClass.OtherM2;我的德尔德尔C =德尔A +德尔B;//有组合的调用列表
尽管结合代表的术语可能给人的印象是操作数代表被修改,它们根本没有改变.在事实上,代表是不可变的.创建委托对象后,无法更改.图 15-6 说明了前面的代码.请注意,操作数委托保持不变.
线程安全和速度是这里的主要关注点.委托更新不是原子的,它需要更新 6 个字段和一个列表.使其原子化以使其不会被破坏需要一个锁,对于这种很少需要线程安全的基本操作来说太昂贵了.
通过使其不可变,委托对象不会被破坏,因为它总是在没有人引用的对象上设置字段.重新分配委托对象引用是原子的,这是基本的 .NET 内存模型保证.所以不再需要锁了.权衡是内存使用效率较低,这是一个小的惩罚.
请记住,线程安全委托更新不会自动使您的代码也成为线程安全的.test-and-fire 代码需要复制引用以避免 NRE,您可以对已取消订阅的方法进行回调.
I was reading a book illustrated C # 2012 in the section Combining Delegates point not notice that? Purpose of the delegates are immutable.
MyDel delA = myInstObj.MyM1;
MyDel delB = SClass.OtherM2;
MyDel delC = delA + delB; // Has combined invocation list
Thread-safety and speed are the primary concerns here. A delegate update is not atomic, it requires updating 6 fields and a list. Making it atomic so it cannot get corrupted requires a lock, far too expensive for such a basic operation that rarely needs to be thread-safe.
By making it immutable, the delegate object cannot get corrupted since it always sets fields on an object that nobody has a reference to yet. Reassigning the delegate object reference is atomic, a basic .NET memory model guarantee. So no need for a lock anymore. The trade-off is less efficient memory use, it is a small penalty.
Do keep in mind that the thread-safe delegate update does not automatically make your code thread-safe as well. The test-and-fire code needs to copy the reference to avoid NRE and you can make a callback to a method that was already unsubscribed.
这篇关于c# 中代表不可变的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!