Generic type parameter and Nullable method overload
Hi
I have this code using generic and nullable:// The first one is for class
public static TResult With<TInput, TResult>(this TInput o,
Func<TInput, TResult> evaluator)
where TResult : class
where TInput : class
// The second one is for struct (Nullable)
public static TResult With<TInput, TResult>(this Nullable<TInput> o,
Func<TInput, TResult> evaluator开发者_开发百科)
where TResult : class
where TInput : struct
Please note the TInput constraint, one is class, the other one is struct. Then I use them in:
string s;
int? i;
// ...
s.With(o => "");
i.With(o => ""); // Ambiguos method
It cause an Ambiguos error. But I also have the another pair:
public static TResult Return<TInput, TResult>(this TInput o,
Func<TInput, TResult> evaluator, TResult failureValue)
where TInput : class
public static TResult Return<TInput, TResult>(this Nullable<TInput> o,
Func<TInput, TResult> evaluator, TResult failureValue)
where TInput : struct
This one compiles successfully
string s;
int? i;
// ...
s.Return(o => 1, 0);
i.Return(o => i + 1, 0);
I got no clues why this happen. The first one seems Ok, but compiles error. The second one ('Return') should be error if the first one is, but compiles successfully. Did I miss something?
Constraints within the generic method are not considered while choosing an overload - they're checked after the overload has been chosen.
Constraints within the types of the parameters are checked as part of choosing an overload. It's a bit confusing, but it makes sense eventually.
I have a blog post on this which may help to understand it further.
Additionally note that your second example has the additional argument which contributes to type inference, which is what makes the difference between the two. TResult
is inferred to be int
, which prevents the first overload from being valid - there's no conversion from (int? x) => x + 1
to Func<int?, int>
whereas there is a conversion from (int x) => x + 1
to Func<int, int>
.
精彩评论