lambda表达式和方法组语句的求值方式有何不同



我正在尝试了解更多关于lambda在C#中如何工作的信息,下面的例子让我有点困惑。

我有一个加权平均函数:

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;
}

在一个地方,我使用了一个返回类型为double:的助手函数

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

并将其作为weight参数传递到加权平均函数中,如下所示:

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

以上内容似乎很有效。

让我困惑的部分是:在一些地方,ReSharper建议我将一些Lambda转换为方法组。试着看看这是怎么回事,我把电话改成了:

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

这导致一个错误,Expected a method with 'double?' GetQuantity(Record) signature

有人能告诉我幕后到底发生了什么吗?为什么lambda表达式不会产生类似的错误,因为GetQuantity函数的返回是double而不是double??方法组与lambda表达式的求值方式有何不同?

谢谢!

lambda表达式没有错误,因为它的返回类型被推断为double?,与委托参数匹配,并且您从方法调用中显式返回了一个double。它的工作原理与此相同:

static double? GetDoubleOrNull() => 0.0d;

double是可为null的double的有效值。

然而,方法组转换有其他需要满足的规则,而且由于它试图匹配委托,其中之一就是委托兼容性。特别是,有一行写着:

存在从M的返回类型到D的返回类型的身份或隐式引用转换。

doubledouble?之间没有标识或隐式引用转换,因此方法组转换失败。一个隐式的可为null的转换,但这在这里不适用。