为什么派生 class 不能用从原始类型派生的类型覆盖其基础 class 中的 属性?
Why can't a deriving class override a property in its base class with a type derived from the original type?
实际上,我想了解为什么这在 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 class 不隐藏 Bar class 中的成员(使用新的或某物)。编译器会知道这是否会发生,所以这似乎不是问题。
我也明白这可以用抽象 classes 来实现,但我特别想更好地理解为什么在非抽象 classes 的情况下不允许这样做.
假设有人使用您的代码:
Foo f = new Boo();
由于引用是 Foo
类型,我们只能假设 Property
是 Bar
类型。所以我们现在也可以这么写:
f.Property = new Boz(); // assuming Boz also derives from Bar
这肯定不是您真正想要的。
您可以使用以下解决方法,但是制作 Foo
通用接口并在 Boo
class
中实现它
interface IFoo<T> where T : Bar
{
public T Property { get; set; }
}
class Boo : IFoo<Baz>
{
public Baz Property { get; set; }
}
还有一个 covariant return types,计划在 C# 9 中使用。但它只适用于只读属性
实际上,我想了解为什么这在 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 class 不隐藏 Bar class 中的成员(使用新的或某物)。编译器会知道这是否会发生,所以这似乎不是问题。
我也明白这可以用抽象 classes 来实现,但我特别想更好地理解为什么在非抽象 classes 的情况下不允许这样做.
假设有人使用您的代码:
Foo f = new Boo();
由于引用是 Foo
类型,我们只能假设 Property
是 Bar
类型。所以我们现在也可以这么写:
f.Property = new Boz(); // assuming Boz also derives from Bar
这肯定不是您真正想要的。
您可以使用以下解决方法,但是制作 Foo
通用接口并在 Boo
class
interface IFoo<T> where T : Bar
{
public T Property { get; set; }
}
class Boo : IFoo<Baz>
{
public Baz Property { get; set; }
}
还有一个 covariant return types,计划在 C# 9 中使用。但它只适用于只读属性