C#:覆盖属性并返回派生类型

时间:2016-09-24 14:42:39

标签: c# override

让我们说我有一个A级的财产"详细信息"返回B类的实例。

public class A
{
    public virtual B Details {get; set;}
}

让我们说,我有一个继承自A的Aext(扩展)类。 但我希望Aext.Details返回类Bext(B扩展)的实例:

public class Aext : A
{
    public override Bext Details {get; set;}
}

这不会编译,因为Bext类型必须与从A继承的类型相匹配 当然,我只需将B作为Aext的详细信息返回即可轻松解决。

public class Aext
{
    B Details {get; set;}
}

分配将起作用,但如果Details是Bext或B,我每次使用Aext实例时都必须检查。

你认为这种解决方案可以做一些更清洁的方法吗?

谢谢。

3 个答案:

答案 0 :(得分:2)

也许你可以试试泛型,像这样:

public class A<T> where T : B
{
    public T Details { get; set; }
}

public class Aext : A<Bext>
{
}

public class B
{

}

public class Bext : B
{

}

如果需要,可以使用Bext Details覆盖T详细信息,它可以正常工作。

答案 1 :(得分:0)

不 - 但我认为这表明基类在设计上存在缺陷。您正在尝试将接口行为强制转换为Abstract类/方法。基本方法什么都不做,究竟是什么继承?基类可以具有由每个继承者访问的类型B的受保护成员,并通过其自己的强类型访问器方法公开。该值可供所有继承者使用,但消费者需要获取/设置强类型版本的数据。

答案 2 :(得分:0)

如果您不想引入接口,可以执行以下操作:

public class B
{ }

public class Bext : B
{ }

public class A
{
    public virtual B Details { get; set; }

    public A()
    {
        Details = new B();
    }

}

public class Aext : A
{
    public override B Details => new Bext();
}

但是,我建议你使用组合并使用依赖注入,如下所示:

public interface IB
{ }
public class B : IB
{ }

public class Bext : IB
{ }

public class A
{
    public virtual IB Details { get; set; }

    public A(IB details)
    {
        Details = details;
    }
}

public class TestClass
{
    public void TestMethod()
    {
        IB details = new B();
        IB extDetails = new Bext();

        A instance1 = new A(details);
        A instance2 = new A(extDetails);
    }
}

这样,您不需要通过创建Aext类来扩展继承层次结构。您可以严格包含相关属性。