If I have a lambda such as () => { throw new Exception(); }, it's unclear whether it has a return type or not. Because of this, it can be (implicitly) converted to both Action and Func<object> (or any other Func<T>). This is because, according to §6.5 Anonymous function conversions of the C# 4 spec:
[A] delegate type
Dis compatible with an anonymous functionFprovided:
…
If
Dhas avoidreturn type and the body ofFis a statement block, when […] the body ofFis a valid statement block in which no return statement specifies an expression.If
Dhas a non-void return type and the body ofFis a statement block, when […] the body ofFis a valid statement block with a non-reachable end point in which eachreturnstatement specifies an expression that is implicitly convertible to the return type ofD.
But if I have two overloads of a method, where one has a parameter of type Action and the other Func<object>, and I pass it the lambda from above, the Func<object> overload is used. Why? Which part of specification says that Func<object> is better than Action in this case?
I have looked at §7.5.3.2 Better function member, but that does not explain it.
I should've looked one section lower: §7.5.3.3 Better conversion from expression explains that:
Given an implicit conversion
C1that converts from an expressionEto a typeT1, and an implicit conversionC2that converts from an expressionEto a typeT2,C1is a better conversion thanC2if at least one of the following holds:
…
Eis an anonymous function,T1is either a delegate typeD1or an expression tree typeExpression<D1>,T2is either a delegate typeD2or an expression tree typeExpression<D2>and one of the following holds:
…
D1andD2have identical parameter lists, and one of the following holds:
…
D1has a return typeY, andD2is void returning
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With