I have this function:
public static U? IfNotNull<T, U>(this T? self, Func<T, U?> func)
where T : struct
where U : struct
{
return (self.HasValue) ? func(self.Value) : null;
}
Example:
int? maybe = 42;
maybe.IfNotNull(n=>2*n); // 84
maybe = null;
maybe.IfNotNull(n=>2*n); // null
I want it to work on implicitly-nullable reference types as well as explicit Nullable<> types. This implementation would work:
public static U IfNotNull<T, U>(this T? self, Func<T, U> func)
where T : struct
where U : class
{
return (self.HasValue) ? func(self.Value) : null;
}
But of course overload resolution does not look at type constraints, so you can’t have both at once. Is there a solution to this?
Well it does… but not the type constraints of the method itself. It looks at type constraints on the parameter types.
In C# 4 (which has optional parameters) you can do this… but I’d really suggest you don’t:
See this blog post for more details of this horrible, horrible hack.
Personally I’d probably just name the two methods differently so that overload resolution didn’t need to work so hard – and neither did the readers of your code.