如何在C#中重写子类的重写方法中的子类型? [英] How to return subtype in overridden method of subclass in C#?
问题描述
我有一个带有over-ridden方法的子类,我知道它总是返回基类中声明的返回类型的特定子类型。如果我以这种方式编写代码,它将无法编译。由于这可能没有意义,让我给出一个代码示例:
I have a subclass with an over-ridden method that I know always returns a particular subtype of the return type declared in the base class. If I write the code this way, it won't compile. Since that probably doesn't make sense, let me give a code example:
class BaseReturnType { }
class DerivedReturnType : BaseReturnType { }
abstract class BaseClass {
public abstract BaseReturnType PolymorphicMethod();
}
class DerivedClass : BaseClass {
// Compile Error: return type must be 'BaseReturnType' to match
// overridden member 'BaseClass.PolymorphicMethod()'
public override DerivedReturnType PolymorphicMethod() {
return new DerivedReturnType();
}
}
有没有办法在C#中实现这一目标?如果没有,那么实现类似目标的最佳方法是什么?为什么不允许这样做?它似乎不允许任何逻辑上的不一致,因为从over-ridden方法返回的任何对象仍然是是BaseReturnType
。也许有些东西我没考虑过。或者原因可能是技术或历史。
Is there any way to accomplish this in C#? If not, what's the best way to achieve something similar? And why isn't it allowed? It doesn't seem to allow any logical inconsistency, since any object returned from the over-ridden method still is BaseReturnType
. Maybe there is something I hadn't considered though. Or maybe the reason is technological or historical.
推荐答案
不幸的是,C#中不支持协变返回类型以进行方法覆盖。 (Ditto contravariant参数类型。)
Unfortunately no, covariant return types aren't supported in C# for method overriding. (Ditto contravariant parameter types.)
如果您正在实现一个接口,您可以使用弱版本明确实现它,并提供具有更强合同的公共版本。对于父类的简单覆盖,你恐怕没有这种奢侈:(
If you're implementing an interface you can implement it explicitly with the "weak" version and also provide a public version with the stronger contract. For simple overriding of a parent class, you don't have this luxury I'm afraid :(
(编辑:Marc有合理的解决方案 - 虽然它非常丑陋,方法隐藏是通常是可读性的坏事。没有冒犯意味着,Marc;)
( Marc has a reasonable solution - although it's pretty ugly, and method hiding is generally a bad thing for readability. No offence meant, Marc ;)
我相信这实际上是一个CLR限制,而不仅仅是一种语言 - 但我可能错了。
I believe this is actually a CLR restriction, not just a language one - but I could well be wrong.
(作为历史问题,Java(该语言)在1.5之前具有相同的限制 - 但它同时获得了协方差作为泛型。)
(As a matter of history, Java (the language) had the same restriction until 1.5 - but it gained covariance at the same time as generics.)
这篇关于如何在C#中重写子类的重写方法中的子类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!