我知道已经有很多解决此问题的解决方案,但我想我想出了一个解决现有解决方案中存在的问题的解决方案。
由于以下原因,我对某些现有解决方案不满意:
- 保罗·特德斯科(Paolo Tedesco)的第一个解决方案: 猫和狗没有共同的基类。
- Paolo Tedesco的第二种解决方案: 有点复杂且难以阅读。
- Daniel Daranas的解决方案: 此方法 可行, 但会因大量不必要的强制转换和Debug.Assert()语句而使您的代码混乱。
- hjb417的解决方案: 此解决方案不允许您将逻辑保留在基类中。在此示例中(调用构造函数),逻辑很简单,但在实际示例中,逻辑并非如此。
我的解决方案
该解决方案应该通过使用泛型和方法隐藏来克服我上面提到的所有问题。
public class Poo { }public class RadioactivePoo : Poo { }interface IAnimal{ Poo Excrement { get; }}public class baseAnimal<PooType> : IAnimal where PooType : Poo, new(){ Poo IAnimal.Excrement { get { return (Poo)this.Excrement; } } public PooType Excrement { get { return new PooType(); } }}public class Dog : baseAnimal<Poo> { }public class Cat : baseAnimal<RadioactivePoo> { }使用此解决方案,您无需覆盖“狗”或“猫”中的任何内容!这是一些用法示例:
Cat bruce = new Cat();IAnimal bruceAsAnimal = bruce as IAnimal;Console.WriteLine(bruce.Excrement.ToString());Console.WriteLine(bruceAsAnimal.Excrement.ToString());
这将输出:“ RadioactivePoo”两次,表明多态性尚未破坏。
进一步阅读
- 显式接口实现
- 新修改器。我没有在此简化的解决方案中使用它,但在更复杂的解决方案中可能需要它。例如,如果您想为baseAnimal创建一个接口,则需要在“ PooType Excrement”的简化版本中使用它。
- 出通用修饰符(协方差)。同样,在此解决方案中我没有使用它,但是如果您想执行类似的操作,例如
MyType<Poo>
从IAnimal返回并MyType<PooType>
从baseAnimal 返回,则需要使用它才能在两者之间进行转换。



