【问题标题】:What is the "correct" way to initialize a C# delegate?初始化 C# 委托的“正确”方法是什么?
【发布时间】:2010-09-20 11:09:55
【问题描述】:

C# 代表对我来说一直很难掌握,所以我很高兴偶然发现logicchild's article on The Code Project web site titled "C# Delegates: Step by Step"。他有一种非常简洁的方式来解释 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;
    }
}

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

【问题讨论】:

    标签: c# .net delegates initialization


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      为了可读性,我总是使用第一种方法。第二个选项使 math.Sum 看起来是一个属性,并且返回的结果是一个 CalculationHandler。就个人而言,我认为这很令人困惑。

      【讨论】:

      • 哇。许多罪行都是“为了可读性”而犯下的,其中最突出的是编写冗长而复杂的代码,而不是编写清晰、简洁的代码。这与可读性相反。
      • 很有趣,我使用第二个来提高可读性。只是表明可读性是主观的
      • @Konrad,long 不会自动等于卷积。并且简短不会自动等于可读。 RegEx 浮现在脑海中......事实上,“更长”的方式更接近于 C# 中其他所有工作的方式。较短的方式可能会令人困惑。我几乎不会调用 CalculationHandler sumHandler1 = new CalculationHandler(math.Sum);犯罪。
      • 不是自动的,是的。但是您的代码增加了不必要的冗余,我发现这很难证明。 “为了可读性”不是理由,而是不合理的主张。
      • @Konrad 我有理由证明为什么我认为它使它更具可读性(遵循现有模式)。我想是个人喜好。 [尊敬地退出评论线程,因为害怕引发激烈的战争]
      【解决方案3】:

      两者都是正确的。

      第二个是编译器提供的快捷方式,两者都确实创建了第一个的代码。

      第一个更清楚地显示了实际发生的情况,而第二个代码更少,因此更易于阅读(一旦您了解实际发生的情况)。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

            我还将通过 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);
                 
            

            【讨论】:

              猜你喜欢
              • 2017-12-09
              • 1970-01-01
              • 2015-01-20
              • 2022-01-21
              • 1970-01-01
              • 1970-01-01
              • 2017-10-03
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多