gpt4 book ai didi

c# - 将子类添加到 List 时,特定于子类的数据是否丢失?

转载 作者:太空狗 更新时间:2023-10-29 23:58:49 24 4
gpt4 key购买 nike

我有一个制作动物列表的函数,其中一些是狗,一些只是动物。该函数将该列表返回给另一个函数,该函数只想提取出狗,这是可能的,因为 Animal 类有一个 bool isDog。

我的问题是,是否可以从动物( parent )类中提取特定于狗(特定于 child )的数据,又名。动物在引擎盖下还能是狗吗?

我尝试过的事情:

  • 使用 isDog bool 提取狗,然后调用 Dog构造函数在返回 a 的函数之外创建一个新的构造函数动物名单
  • 给 dog 类一个接受动物的构造函数,但仍然无法保持尾部长度

我有这两个接口(interface)

public interface IAnimal
{
string eyeColor;
int numLegs;
}

public interface IDog: IAnimal
{
double tailLength;
}

以及这两个实现

public class Animal: IAnimal
{
public string eyeColor{get;set}
public int numLegs {get; set;}
public bool isDog;

public Animal(string eyes, int legs){
this.eyeColor = eyes;
this.numLegs = legs
this.isDog = false;
}
}

public class Dog: Animal, IDog
{
public double tailLength {get;set;}
public Dog(double tail, string eyes)
{
this.tailLength = tail;
this.eyeColor = eyes;
this.numLegs = 4;
this.isDog = true;
}
}

这是两个函数的当前状态

List<Animal> getAnimals()
{
List<Animal> animals;
Animal a1 = new Animal("Blue", 4);
animals.Add(a1);
Animal a2 = new Animal("Green", 2);
animals.Add(a2);
Dog d1 = new Dog(2.3, "Brown");
animals.Add(d1);
Dog d2 = new Dog(3.5, "Black");
animals.Add(d2);
return animals;
}

void foo(){
IEnumerable<IAnimal> sample = getAnimals();
var x = totalTailLength(sample.Where(d => d.isDog));
}

double totalTailLength(IEnumerable<IDog> dogs){
return dogs.Sum(d => d.tailLength);
}

谢谢

最佳答案

是的,你绝对可以做到。如果您使用您的确切代码并修复一些错误,那么您会发现它有效:

  1. 有两个语法错误,您错过了一个分号。

  2. 字段不能是接口(interface)成员,所以你需要让它们成为属性。

  3. Dog需要调用父级的构造函数,这也消除了手动设置这些属性的需要:

    public Dog(double tail, string eyes) : base(eyes, 4)
    {
    this.tailLength = tail;
    this.isDog = true;
    }
  4. getAnimals ,你需要初始化列表:

    List<Animal> animals = new List<Animal>();
  5. foo , sample类型为 IEnumerable<IAnimal> , 所以元素的类型是 IAnimal .然而,该类型没有 isDog属性(因为它在类上而不在接口(interface)上)。因此,要么将类型更改为 IEnumerable<Animal> , 或将成员移动到界面。

  6. totalTailLength期望一个可枚举的 IDog但是sample.Where()返回 IAnimal s(或 Animal s,如上所述)。由于您过滤了元素,因此您应该转换可枚举的:

    var x = totalTailLength(sample.Where(d => d.isDog).Cast<IDog>());

然后所有内容都会编译,如果您实际打印出结果,您会得到正确的结果。

对象的类型不附加到引用该对象的变量,而是附加到对象本身。所以每个 Dog在你的动物列表中仍然知道它是一只狗。这实际上可以让你摆脱 isDog成员,因为您可以使用 is operator 检查对象是否属于特定类型:

IAnimal someAnimal = new Dog();
bool isADog = someAnimal is Dog; // true

您还可以将其与 LINQ 结合使用来过滤 Dog你的元素IAnimal使用 Enumerable.OfType<T> 列出:

var x = totalTailLength(sample.OfType<IDog>());

关于c# - 将子类添加到 List<parent> 时,特定于子类的数据是否丢失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37688271/

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