简体   繁体   English

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

[英]C# : Override a property and return a derived type

Let's say I have a class A with the property "Details" that return an instance of class B. 假设我有一个带有属性“Details”的A类,它返回一个B类实例。

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

Lets say also, I have a class Aext (A extended) that inherits from A. But I want that Aext.Details return an instance of class Bext (B extended) : 也可以说,我有一个继承自A的Aext(扩展)类。但我希望Aext.Details返回类Bext的实例(B扩展):

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

This will not compile because the type Bext must match the type inherited from A. 这将无法编译,因为Bext类型必须与从A继承的类型匹配。
Of course, I can easily solve that by just put B as return of Details for Aext. 当然,我只需将B作为Aext的详细信息返回即可轻松解决。

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

Assignment will work, but I'll have to check everytime I use an instance of Aext if Details is Bext or B. 分配将起作用,但如果Details是Bext或B,我每次使用Aext的实例时都要检查。

Do you see a way of doing something cleaner that this solution ? 你有没有看到这种解决方案做得更清洁的方法?

Thank you. 谢谢。

Maybe you can try generics, something like this: 也许你可以尝试泛型,像这样:

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

public class Aext : A<Bext>
{
}

public class B
{

}

public class Bext : B
{

}

If you need you can override T Details with Bext Details, it will work fine. 如果您需要,可以使用Bext Details覆盖T详细信息,它将正常工作。

No - but I think therefore it indicates the base class is flawed in its design. 不 - 但我认为这表明基类在设计上存在缺陷。 You are trying to force Interface behaviours onto an Abstract class/method. 您正在尝试将接口行为强制转换为Abstract类/方法。 The base method does nothing, do what exactly is being inherited ? 基本方法什么都不做,究竟是什么继承? The base class could have a protected member of type B accessed by each inheritor and exposed via their own strongly typed accessor method. 基类可以具有由每个继承者访问的类型B的受保护成员,并通过其自己的强类型访问器方法公开。 The value would be available to all inheritors, but consumers would need to get/set a strongly typed version of the data. 该值可供所有继承者使用,但消费者需要获取/设置强类型版本的数据。

If you do not want to introduce interfaces, you can do something like this: 如果您不想引入接口,可以执行以下操作:

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();
}

However, I would suggest you go with composition and use dependency injection, like this: 但是,我建议你使用组合并使用依赖注入,如下所示:

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);
    }
}

This way, you do not need to extend the inheritance hierarchy by creating Aext class. 这样,您无需通过创建Aext类来扩展继承层次结构。 You can contain that strictly to the properties in question. 您可以严格包含相关属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM