当前位置: 首页 > 知识库问答 >
问题:

将子类添加到列表时,特定于子类的数据是否丢失?

赖绪
2023-03-14

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

我的问题是,有没有可能从动物(父母)类中提取狗特定(子特定)的数据,也就是。一个动物还能是引擎盖下的狗吗?

我尝试过的事情:

  • 使用isDog bool提取狗,然后调用Dog构造函数在返回动物列表的函数之外创建一个新的狗
  • 给狗类一个构造函数来接收动物,但仍然没有办法保持尾巴长度

我有这两个接口

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);
}

谢谢

共有3个答案

夏英发
2023-03-14

你不能那样做。这是:

sample.Where(d => d.isDog)

将返回一个IENumable

你想从你的收藏中得到狗的类型,比如:

sample.OfType<Dog>()

如果调试代码,可以在调试器中查看运行时的底层属性。试一试,你就能在你的收藏中看到真正的类型。

容学林
2023-03-14

不,当然特定于子类的数据不会丢失。

但是请:

  • 将实例变量定义为private并提供公共属性

如果只需要提取犬类动物,只需使用Linq:

IEnumerable<IDog> dogs = animals.OfType<IDog>();
司徒焕
2023-03-14

是的,你绝对可以做到。如果你使用精确的代码并修复了一些错误,那么你可以看到它是有效的:

>

字段不能是接口成员,因此需要将它们设为属性。

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

public Dog(double tail, string eyes) : base(eyes, 4)
{
    this.tailLength = tail;
    this.isDog = true;
}

getAnimals中,需要初始化列表:

List<Animal> animals = new List<Animal>();

foo中,示例类型为IENumable

totalTailLength要求可枚举的IDogs,但sample。其中()返回IAnimals(或Animals,如上所述)。由于筛选了元素,因此应强制转换可枚举项:

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

然后一切都会编译,如果你真的打印出结果,你会得到正确的结果。

对象的类型不是附加到引用该对象的变量,而是附加到对象本身。所以你的动物列表中的每只狗都知道它是狗。这实际上允许您去掉isDog成员,因为您可以使用is操作符检查对象是否属于特定类型:

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

您还可以使用LINQ使用ENumable来过滤Dog列表中的元素。OfType

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

 类似资料:
  • 我正在尝试使用自定义字段(ACF)的内容向我的自定义帖子类型添加一个新的管理员列。我想添加的字段是“post object”字段,但它只显示文章标题,而不是ACF中的链接文章。我添加了一个截图。 这是我目前掌握的情况:

  • 我想创建一个包含类别的列表,并将类别悬停在需要显示子类别的类别上。我能够在列表中显示父类别。但我不知道如何获得子类别。在我的表中有category\u id、parent\u id列和一些其他列。如果父类别id为“0”,则它是主类别,对于子类别,它包含类别id。因此,现在我需要显示主类别的子类别。我不明白该如何进行。谁能给我提建议。

  • 我希望能够将我的WooCommerce产品发布到我的“帖子”类别中。基于下面的鳕鱼,这是可能的。这是我在functions.php.中使用的代码。当我用吴宇森制作新产品时,这些类别是可以点击的。然而,它并没有发布到类别本身。感谢对此事的任何见解。 将类别选择添加到自定义帖子类型

  • 我正在对地图执行firestore查询 没有人工作过,任何帮助都是感激的 谢谢你抽出时间

  • 如果有人能在这里帮助我,我会非常喜欢它:)

  • 很容易将列表列表转换为数据帧: 但是我如何将df转换回列表列表呢?