c#:重写属性并返回派生类型

本文关键字:返回 派生 类型 属性 重写 | 更新日期: 2023-09-27 18:08:32

假设我有一个类a,它的属性是"Details",它返回一个类b的实例。

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

让我们也说,我有一个类ext (a扩展),继承自a。但是我想要下一个。detail返回类ext (B扩展)的实例:

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

这将无法编译,因为类型Bext必须匹配从a继承的类型。
当然,我可以很容易地解决这个问题,只需将B作为ext的详细信息返回。

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

赋值将工作,但我必须检查每次我使用ext的实例,如果细节是ext或b

你能想到比这个更干净的方法吗?

谢谢。

c#:重写属性并返回派生类型

也许你可以尝试这样的泛型:

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

如果你需要,你可以用ext Details覆盖T Details,它会工作得很好

不——但我认为这表明基类在设计上存在缺陷。您正在尝试将接口行为强制到抽象类/方法上。基方法什么都不做,到底继承了什么?基类可以有一个类型B的受保护成员,由每个继承程序访问,并通过它们自己的强类型访问器方法公开。该值将对所有继承者可用,但消费者需要获取/设置数据的强类型版本。

如果您不想引入接口,您可以这样做:

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);
    }
}
这样,您就不需要通过创建ext类来扩展继承层次结构。