重写方法时无法更改返回类型,使用泛型时出错

时间:2014-05-23 22:20:15

标签: c# generics inheritance abstract-class

我无法覆盖返回强类型泛型类的方法。

这只是为下面的例子设置

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方法,因为类的名称不会更改。但只有第二种方法编译。有什么方法可以避免这种情况吗?

3 个答案:

答案 0 :(得分:4)

第一个覆盖会更改实际签名:

您在基类上的方法确定它将返回AbstractClass<T>

由于您的子类表示T将成为某种东西,现在这意味着该方法返回AbstractClass<Something>。虽然ClassAAbstractClass<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> {}

ClassAClassB都是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接口)。