Csharp/C#教程:为什么我不能使用Lambda表达式取消订阅事件?分享


为什么我不能使用Lambda表达式取消订阅事件?

本文说明您无法使用Lambda表达式取消订阅事件 。

例如,您可以订阅如下:

d.Barked += (s, e) => Console.WriteLine("Bark: {0}", e); 

但你不能这样取消订阅:

 d.Barked -= (s, e) => Console.WriteLine("Bark: {0}", e); 

为什么? 这与代表取消订阅有什么区别,例如

 EventHandler handler = (s, e) => Console.WriteLine("Bark: {0}", e); d.Barked += handler; // ... d.Barked -= handler; 

这一切都归结为:为了代表加法/减法的目的,两位代表何时被认为是相同的。 取消订阅时,它实质上是使用Delegate.Remove的逻辑,如果.Target.Target都匹配,则认为两个Delegate.Remove是等效的(至少对于具有单个目标方法的委托的简单情况;多播更多)很难描述)。 那么:lambda上的.Target.Target是什么(假设我们将它编译为委托 ,而不是表达式 )?

编译器在这里实际上有很多自由,但是会发生什么

然而,它没有做的是比较许多lambda与相似的看起来的身体,以减少任何。 所以我编译代码时得到的是两个静态方法:

 [CompilerGenerated] private static void 
b__0(object s, string e) { Console.WriteLine("Bark: {0}", e); } [CompilerGenerated] private static void
b__2(object s, string e) { Console.WriteLine("Bark: {0}", e); }

(这里的Main只是因为在我的测试装备中那些lambdas在Main方法中 – 但最终编译器可以选择它在这里选择的任何不可发音的名称)

第一种方法由第一种lambda使用; 第二种方法由第二种lambda使用。 所以最终,它不起作用的原因是因为.Method不匹配。

在常规的C#术语中,它会像:

 obj.SomeEvent += MethodOne; obj.SomeEvent -= MethodTwo; 

其中MethodOneMethodTwo内部具有相同的代码; 它没有取消订阅任何东西。

如果编译器发现这一点可能会很好 ,但它不是必需的 ,因此它更安全,它不会选择 – 它可能意味着不同的编译器开始产生非常不同的结果。

作为旁注; 如果它确实试图去重复它可能会非常混乱,因为你也有捕获上下文的问题 – 那么它会在某些情况下“工作”而不是其他情况 – 而不是明显的 – 可能最糟糕的情况。

上述就是C#学习教程:为什么我不能使用Lambda表达式取消订阅事件?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/999710.html

(0)
上一篇 2021年12月27日
下一篇 2021年12月27日

精彩推荐