Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are lambda expressions vs method group statements evaluated differently?

Tags:

c#

.net

lambda

I'm trying to learn more about how lambdas work in C# and I'm a bit confused by the following example.

I have a weighted average function:

public static double? WeightedAverage<T>(this IEnumerable<T> records, Func<T, double?> value, Func<T, double?> weight)
{
    // snip actual calculation code
    if (denominator != 0)
        return numerator / denominator;
    return null;
}

In one place, I use a helper function that has a return type of double:

static double GetQuantity(Record record)
{
    return record.Quantity * record.Factor;
}

And pass that as the weight parameter into the weighted average function like this:

return _records.WeightedAverage(r => r.Price, r => ReportHelpers.GetQuantity(r));

The above seems to work fine.

The part that is confusing to me: In a few places ReSharper has recommended that I convert some of my lambdas into method groups. Playing around to try and see how this works, I changed the call to:

return _records.WeightedAverage(r => r.Price, ReportHelpers.GetQuantity);

This results in an error, Expected a method with 'double?' GetQuantity(Record) signature

Can someone tell me exactly what is happening behind the scenes here? Why does the lambda expression not produce a similar error since the return of the GetQuantity function is double and not double?? What is the difference with how the method group vs lambda expressions are being evaluated?

Thanks!

like image 867
Jim Avatar asked Oct 18 '25 16:10

Jim


1 Answers

The lambda expression doesn't have the error because its return type is inferred to be double?, matching the delegate argument, and you are explicitly returning a double from your method call. It works for the same reason that this works:

static double? GetDoubleOrNull() => 0.0d;

A double is a valid value for a nullable double to have.

A method group conversion, however, has additional rules that it needs to satisfy and, because it's trying to match a delegate, one of them is delegate compatibility. In particular, there is a line that says:

An identity or implicit reference conversion exists from the return type of M to the return type of D.

There is no identity or implicit reference conversion between double and double?, so the method group conversion fails. There is an implicit nullable conversion, but that isn't applicable here.

like image 52
Chris Hannon Avatar answered Oct 20 '25 04:10

Chris Hannon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!