简体   繁体   中英

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" . He has a very succinct way of explaining C# delegates and I can recommend it to you. 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). 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. 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). 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. Resharper will use the second and mark part of the code in the first version as redundant.

Both ways are OK, short version is just C# compiler service. 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.

I will be add also additional variants of the initialization by lambda expression, which can be useful in some cases:

    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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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