简体   繁体   English

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

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

C# delegates have always been difficult for me to grasp and so I was very happy to stumble across logicchild's article on The Code Project web site titled "C# Delegates: Step by Step" . C# 委托对我来说一直很难掌握,因此我很高兴在 The Code Project 网站上偶然发现了logicchild 题为“C# 委托:循序渐进”的文章 He has a very succinct way of explaining C# delegates and I can recommend it to you.他有一种非常简洁的方式来解释 C# 委托,我可以向您推荐。 However, in trying out the examples, I see that are two ways to initialize a delegate, mainly:但是,在尝试示例时,我发现有两种初始化委托的方法,主要是:

    //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);

and

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

where the math class is defined as其中数学类定义为

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

So which is the "correct" way and why?那么哪个是“正确”的方式,为什么?

They are both correct, but method group conversion , which is the second option was added in 2.0 (IIRC). 它们都是正确的,但方法组转换 ,这是第二个选项在2.0(IIRC)中添加。 Ie if you're using an old version of the compiler you need to use the first option. 即如果您使用旧版本的编译器,则需要使用第一个选项。 Otherwise the extra typing is really redundant. 否则,额外的打字真的是多余的。

I always use the first method for the sake of readability. 为了便于阅读,我总是使用第一种方法。 The second option makes it appear that math.Sum is a property and is returning a result that is a CalculationHandler. 第二个选项使得math.Sum是一个属性,并返回一个CalculationHandler结果。 Personally, I think that's confusing. 就个人而言,我认为这令人困惑。

Both are correct. 两者都是正确的。

The second one is a shortcut provided by the compiler, both does actually create the code of the first one. 第二个是编译器提供的快捷方式,它们实际上都创建了第一个的代码。

The first one shows more clearly what's actually happening, while the second one is less code so it's easier to read (once you understand what's really happening). 第一个更清楚地显示了实际发生的情况,而第二个是更少的代码,所以它更容易阅读(一旦你理解了真正发生的事情)。

Personnaly I preferre the second option (method group conversion). Personnaly我更喜欢第二个选项(方法组转换)。 From a functional point of view I don't care about the type of delegate, since that will not give me any hints to what the method assigned to the delegate is doing when invoked. 从功能的角度来看,我并不关心委托的类型,因为这不会给我任何关于调用时分配给委托的方法的提示。 The method name will (at least should) however give me a good idea of what's going to happen when the delegate is invoked and in the second option I don't have to search for the method name. 然而,方法名称(至少应该)让我很好地了解调用委托时会发生什么,而在第二个选项中我不必搜索方法名称。

As a side note VS will give you the first version if you use autocomplete with event handler registration. 作为附注,如果您使用自动完成功能和事件处理程序注册,VS将为您提供第一个版本。 Resharper will use the second and mark part of the code in the first version as redundant. Resharper将使用第二个并将第一个版本中的代码部分标记为冗余。

Both ways are OK, short version is just C# compiler service. 两种方式都可以,短版本只是C#编译服务。 The first way is more verbose and shows exactly what happens. 第一种方式更详细,并准确显示发生了什么。 Both versions produce the same IL code, which is actually close to the first version. 两个版本都生成相同的IL代码,实际上接近第一个版本。

I will be add also additional variants of the initialization by lambda expression, which can be useful in some cases:我还将添加 lambda 表达式初始化的其他变体,这在某些情况下很有用:

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

I don't fully believe that the IL code in all cases will be the same (i didn't check it, with lambda expression can exist the "intermediate call"/"variable"), but the last can give additional variants to call the method我不完全相信所有情况下的 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