我无法覆盖返回强类型泛型类的方法。
这只是为下面的例子设置
public class Something : ISomething {}
public interface ISomething {}
我的问题在于下面的Clone
方法,只有第二种方法有效。
public class ClassA : AbstractClass<Something>
{
public override ClassA Clone() // <--- this doesn't work
{
return this; // this is just dummy code
}
public override AbstractClass<Something> Clone() // <-- this works
{
return this; // this is just dummy code
}
}
public abstract class AbstractClass<T> where T : ISomething
{
public abstract AbstractClass<T> Clone();
}
我更希望使用第一个Clone
方法,因为类的名称不会更改。但只有第二种方法编译。有什么方法可以避免这种情况吗?
答案 0 :(得分:4)
第一个覆盖会更改实际签名:
您在基类上的方法确定它将返回AbstractClass<T>
。
由于您的子类表示T
将成为某种东西,现在这意味着该方法返回AbstractClass<Something>
。虽然ClassA
是AbstractClass<Something>
,但并不意味着所有AbstractClass<Something>
都是ClassA
。
考虑以下示例:
AbstractClass<Something> myVar = new ClassA(); // works, because ClassA is an AbstractClass<Something>
// Now we hold a reference to an AbstractClass<Something>
myVar.Clone(); // => This should return an AbstractClass<Something> not ClassA
扩展示例:考虑ClassB:
public class ClassB : AbstractClass<Something> {}
ClassA
和ClassB
都是AbstractClass<Something>
。如果我们重新开始第一个例子:
AbstractClass<Something> myVar;
myVar = new ClassA();
myVar = new ClassB();
// Here you don't know whether it's a ClassA or ClassB, you only know it's an `AbstractClass<Something>`
myVar.Clone();
答案 1 :(得分:1)
您可以为返回类型添加另一个通用参数:
public abstract class AbstractClass<TC, T> where TC: AbstractClass<TC, T> where T : ISomething
{
public abstract TC Clone();
}
然后将ClassA
更改为:
public class ClassA : AbstractClass<ClassA, Something>
{
public override ClassA Clone()
{
return this;
}
}
答案 2 :(得分:1)
重写方法时无法更改返回类型。
您可以从第一个实现中删除覆盖,这将定义一个新方法。但是,因为你在基类中有那个抽象的Clone方法,所以你也被迫实现它,你最终将得到两个具有相同名称和相同参数的方法,因此代码将无法编译。 / p>
你真的需要抽象类中的Clone方法吗?
我认为你应该从抽象类中删除Clone方法,并在派生类中添加Clone方法(也许还实现了ICloneable接口)。