gpt4 book ai didi

c# - 用更多的派生类型覆盖子类继承的属性

转载 作者:太空狗 更新时间:2023-10-29 22:09:06 26 4
gpt4 key购买 nike

我试图实现的一个简化示例如下所示:

public class Animal
{
public virtual Teeth teeth {get;set;}
}

public class Mouse : Animal
{
public override SmallTeeth teeth {get; set;} // SmallTeeth Inherits from Teeth
}

这显然是行不通的,因为 dentry 必须与 Animal 类中的类型相同才能在 Mouse 类中被覆盖。但是,在允许我在从 Animal 继承的任何函数中使用更多派生类型的情况下,可以实现这样的事情吗?例如,如果 Animal 类包含一个咬的函数:

public void Bite()
{
teeth.bite()
Console.WriteLine("Ouch")
}

我可以调用继承自 Animal 的 Bite() 函数,它会使用类型为 SmallTeeth 的 Mouse 类字段。这可能吗?这是做我想做的事情的最好方法吗?如果不是,解决这个问题的正确方法是什么?

最佳答案

注意:这个答案写于 2016 年。从那以后,返回类型协变(令人惊讶地!)被添加到 C# 中。阅读此答案时请记住这一点。


您想要的功能称为返回类型协方差,C# 不支持它。 (顺便说一句,C++ 会。)

协变返回类型的通常情况是:

abstract class Animal
{
public abstract Cage GetCage();
}
public class Fish : Animal
{
public override Aquarium GetCage() { ... }
}

这不合法,但如果合法,那将是安全的。也就是说,如果您手头有一个 Animal 并且您要一个笼子,即使它是一条鱼,您也会得到一个。为什么?因为水族箱是一种笼子。

你提出的建议不仅不合法,而且不安全:

Animal animal = new Mouse();
animal.Teeth = new TRexTeeth();

契约是任何一种 dentry 都可以召唤二传手。通过使派生类对其可以接受的内容更具限制性,您违反了基类的契约。

所以不要那样做。

虽然有很多方法可以在 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 的属性。

我在这里描述另一种解决这个问题的方法:

Does C# support return type covariance?

另一个答案中给出的通用解决方案也有效,但我个人更喜欢将泛型排除在外,除非有必要。

搜索“C# 中的返回类型协方差”以获取有关此模式的更多信息。

关于c# - 用更多的派生类型覆盖子类继承的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35537666/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com