为什么派生类不能用从原始类型派生的类型覆盖其基类中的属性?

问题描述

有效地,我想了解为什么在C#中这是不可能的:

class Foo{
    public Bar Property {get;set;}
}

class Boo : Foo{
    public override Baz Property {get;set;}
}

class Bar{
    //some internal stuff
}

class Baz : Bar{
    //more stuff
}

对我来说,在大多数情况下,只要Baz类没有从Bar类中隐藏成员(无论是new还是其他东西),这似乎就可以明确定义行为。编译器会知道这种情况是否会发生,所以似乎是一种非问题。

我也理解可以使用抽象类来实现,但是我特别想更好地理解为什么在非抽象类中不允许这样做。

对不起,如果这是一个愚蠢的问题,我真的很想更好地理解语言的这一方面。

解决方法

想象有人使用您的代码:

Foo f = new Boo();

由于引用的类型为Foo,因此我们只能假定Property的类型为Bar。所以我们现在也可以这样写:

f.Property = new Boz(); // assuming Boz also derives from Bar

这肯定不是您真正想要的。

,

您可以使用以下解决方法,但要制作Foo通用接口并在Boo类中实现它

interface IFoo<T> where T : Bar
{
    public T Property { get; set; }
}

class Boo : IFoo<Baz>
{
    public Baz Property { get; set; }
}

还有一个用C#9计划的covariant return types。但它仅适用于只读属性