This static method compiles:
public static void Foo<TValue>(Func<TValue> factory = null)
{
factory?.Invoke();
}
And why wouldn't it? This one, however, doesn't:
public static void Foo<TValue>(Func<TValue> factory = null)
{
var x = factory?.Invoke();
}
Using the return value seems to make a difference:

Of course, the operator ?. isn't applied to an operand of type TValue, but to one of type Func<TValue>, which is why it works when not using the expression value.
The non-generic case works just fine:
public static void Bar(Func<String> factory = null)
{
var x = factory?.Invoke();
}
Try adding where TValue: class to make sure TValue can be null:
static void Foo<TValue>(Func<TValue> factory = null) where TValue: class
In that case, compiler can deduce type of x as TValue and assign null to it when needed (e.g. in the case factory == null).
Or try
static void Foo<TValue>(Func<TValue> factory = null) where TValue: struct
In that case, the deduced type would be TValue?. (Credit goes to @hvd.)
Just think through what type factory?.Invoke(); should resolve to. (An exercise you'd need to do if you didn't use var here.) What type should it be?
To determine what type it needs to be think through how the value is computed. If the delegate is not null you need to invoke it and resolve the operation to a TValue, which is whatever the delegate returns. But if the delegate is null that expression, factory?.Invoke();, needs to resolve to null, so TValue, needs to be a nullable type. So what if TValue isn't nullable, if it's not, then that expression can't be of type TValue, but then what should it be?
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