我有一个带有over-ridden方法的子类,我知道它总是返回基类中声明的返回类型的特定子类型.如果我以这种方式编写代码,它将无法编译.既然这可能没有意义,让我举一个代码示例:
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方法返回的任何对象仍然存在is BaseReturnType
.也许有些东西我没考虑过.或者原因可能是技术或历史.
遗憾的是,C#中不支持协变返回类型以进行方法重写.(Ditto逆变参数类型.)
如果您正在实现一个接口,您可以使用"弱"版本明确地实现它,并提供具有更强合同的公共版本.对于父类的简单覆盖,你不会有这种奢侈我害怕:(
(编辑:Marc有一个合理的解决方案 - 虽然它非常丑陋,隐藏方法通常对可读性不利.没有冒犯意味着,Marc;)
我相信这实际上是一种CLR限制,而不仅仅是语言限制 - 但我可能错了.
(作为历史问题,Java(该语言)在1.5之前具有相同的限制 - 但它在泛型的同时获得了协方差.)
如果不困扰你,你可以使该类成为通用的:
class BaseReturnType { } class DerivedReturnType : BaseReturnType { } abstract class BaseClasswhere T : BaseReturnType { public abstract T PolymorphicMethod(); } class DerivedClass : BaseClass { // Error: return type must be 'BaseReturnType' to match // overridden member 'BaseClass.PolymorphicMethod()' public override DerivedReturnType PolymorphicMethod() { return new DerivedReturnType(); } }
如果引入一个额外的方法来覆盖(因为你不能override
和new
同一类型的同名方法),你可以这样做:
abstract class BaseClass { public BaseReturnType PolymorphicMethod() { return PolymorphicMethodCore();} protected abstract BaseReturnType PolymorphicMethodCore(); } class DerivedClass : BaseClass { protected override BaseReturnType PolymorphicMethodCore() { return PolymorphicMethod(); } public new DerivedReturnType PolymorphicMethod() { return new DerivedReturnType(); } }
现在,您PolymorphicMethod
在每个级别都有一个具有正确类型的方法.