我有这样的公共职能:
public static T Get<T>(this Mango m, T defaultValue = default(T)) where T : class
{
//do something; return something;
}
public static T? Get<T>(this Mango m, T? defaultValue = default(T?)) where T : struct
{
//do something; return something;
}
基本上我想单独处理引用类型和可为空的类型。它编译;直到我要求值类型。对于引用类型,它会编译。
mango.Get<string>(); // compiles..
mango.Get(""); // compiles..
mango.Get<int>(); // The type 'int' must be a reference type in order to use it as
// parameter 'T' in the generic type or method Get<T>(Mango, T)
//also // The call is ambiguous between the following methods or properties:
// Get<int>(Mango, int) and Get<int>(Mango, int?)
这里有什么真正的歧义?什么时候,T
它int
不能适当地调用结构重载吗?还:
mango.Get<int>(0); // The type 'int' must be a reference type in order to use it as
// parameter 'T' in the generic type or method Get<T>(Mango, T)
为什么编译器只检测引用类型重载?我尝试了两个单独的重载:
public static T Get<T>(this Mango m) where T : class
{
return default(T);
}
public static T? Get<T>(this Mango m) where T : struct
{
return default(T);
}
public static T Get<T>(this Mango m, T def) where T : class
{
return default(T);
}
public static T? Get<T>(this Mango m, T? def) where T : struct
{
return default(T);
}
问题仍然存在。显然,前两种方法在这里不能编译,因为重载不仅仅基于约束。
我尝试通过删除受class
约束的重载并仅保留受约束的重载struct
,如下所示:
public static T? Get<T>(this Mango m, T? defaultValue = default(T?)) where T : struct
{
//do something; return something;
}
mango.Get<int>(); // voila compiles!
mango.Get<int>(0); // no problem at all..
// but now I can't have mango.Get<string>() for instance :(
我只剩下重命名这两个函数了吗?我觉得有一个统一的名字是合适的,这样调用者就不必担心实现细节,而只需调用Get
任何类型。
更新:如果我必须避免使用可选参数,Marc 的解决方案将不起作用。
mango.Get<int>(); // still wouldnt work!!
但还有更多的魔力:(:(
public static bool IsIt<T>(this T? obj) where T : struct
{
return who knows;
}
public static bool IsIt<T>(this T obj) where T : class
{
return perhaps;
}
无论如何,我期望相同的编译器错误(根据我)来惹恼我。但是这次不行。
Guid? g = null;
g.IsIt(); //just fine, and calls the struct constrained overload
"abcd".IsIt(); //just fine, and calls the class constrained overload
因此,如果像 Marc 所说的那样,如果重载解决方案在约束检查之前出现,那么这次我不应该得到同样的错误吗?但不是。为什么会这样??这到底是怎么回事?:X