我遇到了一个重载方法的问题,这些方法具有不同的约束,似乎是排他的。那是我的例子:
public class A
{
public void Do<T>() where T : class
{
}
public void Do<T>() where T : struct
{
}
}
并且这不会与以下错误“已定义相同签名的成员”一起编译。是否可以同时满足这两个条件,或者这只是 C# 编译器的限制?
我遇到了一个重载方法的问题,这些方法具有不同的约束,似乎是排他的。那是我的例子:
public class A
{
public void Do<T>() where T : class
{
}
public void Do<T>() where T : struct
{
}
}
并且这不会与以下错误“已定义相同签名的成员”一起编译。是否可以同时满足这两个条件,或者这只是 C# 编译器的限制?
这不是编译器的限制——它是语言的限制(很可能还有 CLR;我不确定)。
从根本上说,这些是冲突的重载——就像试图通过返回类型重载一样。不支持。
可以声明方法,使这些调用都编译为不同方法的调用:
a.Do<int>();
a.Do<string>();
a.Do<int?>();
...但它总是涉及可选参数和/或参数数组,这太可怕了。
另请注意,虽然您不能通过泛型约束重载,但可以通过泛型“arity”(类型参数的数量)重载:
public void Foo() {}
public void Foo<T>() {}
public void Foo<T1, T2>() {}
您不能通过改变泛型参数包含来重载方法。对于有效的方法重载,您必须对该方法具有不同的输入参数。
编译时,这两种方法都应具有以下名称:
A.Do``1
由于泛型参数的计数进入方法或类的名称。
不确定您的情况如何,但您可能需要使用反射来调用这些方法:
public class A
{
public void Do<T>()
{
if(typeof(T).IsValueType){
// nasty reflection to call DoValueType
}
else {
// nasty reflection to call DoReferenceType
}
}
private void DoReferenceType<T>() where T : class {
}
private void DoValueType<T>() where T : struct {
}
}