0

我确定这一定是重复的,但我找不到答案:

如果我有两节课:

public class BASE
{
    public BASE() {};
    public abstract BASE clone();
}


public class CHILD : BASE
{

    public CHILD() : base() {}
    public override BASE clone()
    {
        return new CHILD();
    }
}

每次我想克隆 CHILD 类型的对象时,我都必须进行显式转换,例如:

var a = new CHILD();
CHILD b = a.clone() as CHILD;

有没有办法避免这种转换?我希望能够写:

var original = new CHILD();
BASE copy1 = original.clone();
CHILD copy2 = original.clone();

这在 C# 中可能吗?

4

3 回答 3

3

有没有办法避免这种转换?

不是通过重载Clone——你不能仅仅通过改变它的返回类型来重载一个方法。请改用其他方法:

public class CHILD : BASE
{

    public CHILD() : base() {}
    public BASE clone() { return this.cloneChild();}
    public CHILD cloneChild()
    {
        return new CHILD();
    }
}

如果您想在所有继承的类上强制执行该行为,您可以将其设为BASE通用:

public abstract class BASE<T> where T:BASE<T>
{
    public BASE() {}
    public abstract T clone();
}


public class CHILD : BASE<CHILD>
{

    public CHILD() : base() {}
    public override CHILD clone()
    {
        return new CHILD();
    }
}
于 2016-05-12T13:51:42.210 回答
1

如果您需要CHILDtype 而不是BASEtype in clone,那么您需要进行方法隐藏而不是方法覆盖。您应该删除override关键字并new改用:

public class BASE
{
    public BASE() {};
    public abstract BASE clone();
}

public class CHILD : BASE
{

    public CHILD() : base() {}
    public new CHILD clone()
    {
        return new CHILD();
    }
}
于 2016-05-12T13:52:00.897 回答
0

C# 不支持返回类型协方差。您可以尝试这种解决方法(使用泛型):

public class Base<T> {
    public abstract T Clone()
}

public class Child : Base<Child> {
    public override Child Clone() {
        return ...;
    }
}
于 2016-05-12T13:55:25.557 回答