考虑以下类:
public abstract class Animal { public abstract Animal GiveBirth(); } public class Monkey : Animal { public override Animal GiveBirth() { return new Monkey(); } } public class Snake : Animal { public override Animal GiveBirth() { return new Snake(); } } //That one doesnt makes sense. public class WeirdHuman: Animal { public override Animal GiveBirth() { return new Monkey(); } }
我正在寻找一种强制覆盖GiveBirth方法的返回类型的方法,以便它总是返回实际的类类型,这样没有WeirdHuman可以生成一个Monkey.
我觉得答案是关于泛型类型的,但我看不出我能做到这一点.
预期结果的例子:
public abstract class Animal { public abstract /*here a way to specify concrete type*/ GiveBirth(); } public class Monkey : Animal { public override Monkey GiveBirth() //Must returns an actual Monkey { return new Monkey(); } }
如果清楚地解释,“绝对不可能”可能是一个答案.
解决方法
这是共变量返回,C#不支持.我每天都感叹.你可以做的最好的办法就是使用泛型返回类型并在泛型类型上指定where条件,但是这也可能导致你在遇到通用参数要求的情况下遇到其他问题.
public abstract class Animal<TBirthType> where TBirthType : Animal<TBirthType> { public abstract TBirthType GiveBirth(); } public class Monkey<TBirthType> : Animal<TBirthType> where TBirthType : Monkey<TBirthType> { public override TBirthType GiveBirth() { return new Monkey<Monkey>(); } }
或者,如果您不需要任何进一步的继承,则可以关闭通用.
public class Monkey : Animal<Monkey> { public override Monkey GiveBirth() { return new Monkey(); } }
请注意,仅协方差仍然不足以确保不会形成行为不当的派生类型,但它将允许将返回类型指定为正在使用的类型.但是仍然没有办法将它从抽象类中锁定下来.您可以通过从基础级别实现的方法的反射来管理运行时检查,该方法将在运行时检查类型,但这也可能非常混乱.