【问题标题】:Are extension methods guaranteed to return equal delegates扩展方法是否保证返回相等的委托
【发布时间】:2019-11-12 10:11:44
【问题描述】:

根据 Jon Skeet 的 answer 匿名函数不能保证返回相等的委托:

C# 规范明确指出 (IIRC) 如果你有两个 匿名函数(匿名方法或 lambda 表达式)它可能 或者可能不会从该代码创建相等的委托。 (两名代表是 如果它们具有相同的目标并引用相同的方法,则相等。)

给出的问题代码示例

button.Click += (s, e) => MessageBox.Show("Woho");
button.Click -= (s, e) => MessageBox.Show("Woho");

扩展方法的情况也一样吗?为了示例简单起见,让我们忽略扩展 string 是否是个好主意:

var text = "Woho";   
// extension method body is MessageBox.Show(text)
button.Click += text.ShowMessageBoxExtension; 
button.Click -= text.ShowMessageBoxExtension; // can you safely unsubscribe using delegate2?

var delegate1 = text.ShowMessageBoxExtension; 
var delegate2 = text.ShowMessageBoxExtension;
Debug.Assert(delegate1 == delegate2); // or more precisely is this always true?

【问题讨论】:

    标签: c# delegates extension-methods


    【解决方案1】:

    这是一个关于引用的问题,委托只是一个对象表示方法。所以这一切都归结为引用的相等性,请参阅下面的代码来呈现问题:

    // Here we are creating anonymous functions with lambdas,
    // every time we create different object.
    Action d1 = () => Console.WriteLine("");
    Action d2 = () => Console.WriteLine("");
    d1==d2;
    // false
    // Here we use already defined method, one object represenitng the method.
    d1 = Console.WriteLine;
    d2 = Console.WriteLine;
    d1 == d2;
    // true
    

    【讨论】:

    • 因此,如果我正确理解 Jon Skeet 的回答,d1d2 由于优化可以引用相同的方法(编译器只发出一种方法,或者它可以选择发出两种方法)。当涉及到扩展方法时,编译器在这件事上没有发言权,因为它们已经在某处定义(作为某个类的成员)。
    猜你喜欢
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 2013-08-19
    • 2015-03-22
    相关资源
    最近更新 更多