泛型类型参数和可空方法重载 [英] Generic type parameter and Nullable method overload

查看:244
本文介绍了泛型类型参数和可空方法重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我用这个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆