假设我有两种表格的通用重载方法:
public string Do<T>(T maybeValue, Func<T, string> func)
where T : class
{
if(maybeValue == null) return null;
return func(maybeValue);
}
public string Do<T>(T? maybeValue, Func<T, string> func)
where T : struct
{
if(!maybeValue.HasValue) return null;
return func(maybeValue.Value);
}
现在,使用类型为nullable的变量调用方法,C#拒绝编译并说两次重载之间的调用不明确:
int? maybeX = 3;
Do(maybeX, x => x.ToString());
以下方法或属性之间的调用不明确: &#39;
Program.Do<int?>(int?, System.Func<int?,string>)
&#39;和 &#39;Program.Do<int>(int?, System.Func<int,string>)
&#39;
简单修复是在调用方法时包含泛型参数,或指定lambda参数的类型:
Do<int>(maybeX, x => x.ToString());
Do(maybeX, (int x) => x.ToString());
有趣的是,在调用期间选择int?
作为泛型类型将无法编译
该类型必须是引用类型才能将其用作参数&#39; T&#39;在通用类型或方法中#34;。
为什么?显然,两个重载中只有一个可以使用类型int?
的值,但编译器说调用是不明确的。我是否可以进一步约束方法以帮助编译器决定调用哪个方法,而不必让调用代码明确指定类型?
答案 0 :(得分:3)
where T : class
约束不是方法签名的一部分。该检查稍后在方法过载选择过程中发生
这就是为什么它被认为是模棱两可的。在检查任何约束之前,两种方法都匹配
如果您明确说Do<int?>
,则只有第一种方法匹配,但约束“踢入”并确定它无效,因为int?
不是引用类型。
如果您将其更改为:
,则会选择第二种方法public static string Do<T>(T? maybeValue, Func<T?, string> func)
where T : struct