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

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

我的问题是,是否有可能从动物(父)类中提取狗特定的(特定于儿童的)数据.一只动物还能成为引擎盖下的狗吗?

我尝试过的事情:

>使用isDog bool抽出狗,然后叫狗
构造函数在返回函数的函数之外创建一个新函数
动物名单
>给狗类一个接收动物的构造函数,但仍然
无法保留尾巴长度

我有这两个接口

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

谢谢

最佳答案
是的,你绝对可以做到这一点.如果您使用确切的代码并修复了一些错误,那么您可以看到它的工作原理:

>有两个语法错误,您错过了分号.
>字段不能是接口成员,因此您需要使它们成为属性.
> Dog需要调用父的构造函数,这也消除了手动设置这些属性的需要:

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

>在getAnimals中,您需要初始化列表:

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

>在foo中,样本的类型为IEnumerable< IAnimal>,因此元素的类型为IAnimal.然而,该类型没有isDog属性(因为它在类上但在接口上没有).因此要么将类型更改为IEnumerable< Animal>,要么将成员移动到界面.
> totalTailLength需要一个可枚举的IDog,但是sample.Where()返回IAnimals(或者动物按照上面的内容).由于您筛选了元素,因此应该强制转换枚举:

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

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

对象的类型不会附加到引用该对象的变量,而是附加到对象本身.因此,动物清单中的每只狗都知道它是一只狗.这实际上允许您摆脱isDog成员,因为您可以使用is operator检查对象是否属于特定类型:

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

您也可以使用LINQ来使用Enumerable.OfType<T>过滤IAnimal列表中的Dog元素:

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

转载注明原文:c# – 将Child类添加到List时,特定于子级的数据是否丢失? - 代码日志