泛型类型参数和可空方法重载 [英] Generic type parameter and Nullable method overload
问题描述
喜
我用这个code通用的,可为空的:
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
请注意TInput约束,一个是类,另一种是结构。然后,我用他们:
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
这会导致Ambiguos错误。但我也有另一对:
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.
此外请注意,你的第二个例子中有这有助于类型推断,这是什么使这两者之间的区别的附加参数。 TResult
被推断为 INT
,其中prevents被有效的第一过载 - 有没有从转换(INT X')=&GT; X + 1
到 Func键&LT; INT?INT&GT;
而存在的是的距离 A转换(中间体X)=&GT; X + 1
到 Func键&LT; INT,INT&GT;
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>
.
这篇关于泛型类型参数和可空方法重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!