繁体   English   中英

初始化 C# 委托的“正确”方法是什么?

[英]What is the "correct" way to initialize a C# delegate?

C# 委托对我来说一直很难掌握,因此我很高兴在 The Code Project 网站上偶然发现了logicchild 题为“C# 委托:循序渐进”的文章 他有一种非常简洁的方式来解释 C# 委托,我可以向您推荐。 但是,在尝试示例时,我发现有两种初始化委托的方法,主要是:

    //create a new instance of the delegate class
    CalculationHandler sumHandler1 = new CalculationHandler(math.Sum);
    //invoke the delegate
    int result = sumHandler1(8, 9);
    Console.WriteLine("Result 1 is: " + result);

    CalculationHandler sumHandler2 = math.Sum;
    //invoke the delegate
    int result = sumHandler2(8, 9);
    Console.WriteLine("Result 2 is: " + result);

其中数学类定义为

public class math
{
    public int Sum(int x, int y)
    {
        return x + y;
    }
}

那么哪个是“正确”的方式,为什么?

它们都是正确的,但方法组转换 ,这是第二个选项在2.0(IIRC)中添加。 即如果您使用旧版本的编译器,则需要使用第一个选项。 否则,额外的打字真的是多余的。

为了便于阅读,我总是使用第一种方法。 第二个选项使得math.Sum是一个属性,并返回一个CalculationHandler结果。 就个人而言,我认为这令人困惑。

两者都是正确的。

第二个是编译器提供的快捷方式,它们实际上都创建了第一个的代码。

第一个更清楚地显示了实际发生的情况,而第二个是更少的代码,所以它更容易阅读(一旦你理解了真正发生的事情)。

Personnaly我更喜欢第二个选项(方法组转换)。 从功能的角度来看,我并不关心委托的类型,因为这不会给我任何关于调用时分配给委托的方法的提示。 然而,方法名称(至少应该)让我很好地了解调用委托时会发生什么,而在第二个选项中我不必搜索方法名称。

作为附注,如果您使用自动完成功能和事件处理程序注册,VS将为您提供第一个版本。 Resharper将使用第二个并将第一个版本中的代码部分标记为冗余。

两种方式都可以,短版本只是C#编译服务。 第一种方式更详细,并准确显示发生了什么。 两个版本都生成相同的IL代码,实际上接近第一个版本。

我还将添加 lambda 表达式初始化的其他变体,这在某些情况下很有用:

    Func<int, int, int> func = Sum;
    func = new Func<int, int, int>(Sum);
    func = (x, y) => Sum(x, y);

我不完全相信所有情况下的 IL 代码都会相同(我没有检查它,使用 lambda 表达式可以存在“中间调用”/“变量”),但最后一个可以提供额外的变体来调用方法

func = (int _, int y) => Sum(5, y);
func = (_, y) => Sum(5, y);
     

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM