使用更多派生类型覆盖子类inheritance的属性
我想要实现的简化示例如下所示:
public class Animal { public virtual Teeth teeth {get;set;} } public class Mouse : Animal { public override SmallTeeth teeth {get; set;} // SmallTeeth Inherits from Teeth }
这显然不起作用,因为牙齿必须与要在Mouse类中重写的Animal类中的相同类型。 但是,在允许在从Animalinheritance的任何函数中使用更多派生类型的情况下,可以实现这样的事情吗? 例如,如果Animal类包含一个咬合函数:
public void Bite() { teeth.bite() Console.WriteLine("Ouch") }
我可以调用inheritance自Animal的Bite()
函数,它将使用SmallTeeth
类型的Mouse类’字段。 这可能吗? 这是我做我想做的最好的方式吗? 如果没有,这个问题的正确方法是什么?
您想要的function称为返回类型协方差 ,C#不支持它。 (顺便说一句,C ++确实如此。)
协变返回类型的常见情况是:
abstract class Animal { public abstract Cage GetCage(); } public class Fish : Animal { public override Aquarium GetCage() { ... } }
这不合法,但如果它是合法的,那将是安全的 。 也就是说,如果你手中有一只动物并且你要求一只笼子,即使它是一条鱼,你也会得到它。 为什么? 因为水族馆是一种笼子。
你提出的建议不仅非法,而且不安全:
Animal animal = new Mouse(); animal.Teeth = new TRexTeeth();
合同是可以用任何种类的牙齿调用定位器。 通过使派生类在其可接受的内容中更具限制性,您违反了基类的合同。
所以不要这样做。
有很多方法可以让你在C#中实现你想要的东西。
这只是其中之一:
interface IAnimal { Teeth Teeth { get; } // READ ONLY } class Mouse : IAnimal { private SmallTeeth smallTeeth; public SmallTeeth Teeth { get { return smallTeeth; } } Teeth IAnimal.Teeth { get { return this.Teeth; } } }
现在,如果您将鼠标转换为IAnimal,则会获得返回Teeth的属性,如果您通常使用鼠标,则会获得返回SmallTeeth的属性。
我在这里描述了另一种解决这个问题的方法:
C#是否支持返回类型协方差?
另一个答案中给出的通用解决方案也有效,但我个人更喜欢将generics保留在其中,除非必要。
有关此模式的更多信息,请搜索“C#中的返回类型协方差”。
其实,是。 您可以但不应该为此目的使用generics
,包括类型约束( 请参阅下面 的 注释以及Eric Lippert的post,他详细解释了您在您的情况下想要或想要实现的目标):
public class Animal where T : Teeth { public virtual T teeth {get;set;} } public class Mouse : Animal { public override SmallTeeth teeth {get; set;} // SmallTeeth Inherits from Teeth }