我正在尝试了解更多关于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的返回类型的身份或隐式引用转换。
double
和double?
之间没有标识或隐式引用转换,因此方法组转换失败。是一个隐式的可为null的转换,但这在这里不适用。