C#中基类Animal列表能否通过AddRange添加至派生类Giraffe列表?
问题分析与解决方案
为什么AddRange(animals.OfType<Giraffe>())返回空列表
OfType<Giraffe>()的作用是从集合中筛选实际运行时类型为Giraffe的元素,但你往animals里添加的都是new Animal()实例,这些对象的实际类型是Animal,不是Giraffe,所以这个方法自然返回空集合。
而你自己实现的AddGiraffe()方法本质是属性映射:遍历Animal对象,将其属性值复制到新创建的Giraffe实例中,同时做了去重判断,这和OfType<T>的类型筛选逻辑完全不同。
用AddRange实现需求的正确方式
如果要通过AddRange()实现和AddGiraffe()相同的效果,需要先把符合条件的Animal对象转换为Giraffe实例,再添加到集合中,代码示例如下:
// 替换注释掉的AddRange代码,实现和AddGiraffe一致的逻辑 var newGiraffes = animals // 筛选AnimalType为Giraf的元素 .Where(ani => ani.AnimalType == "Giraf") // 排除已经存在于giraffes中的重复元素 .Where(ani => !giraffes.Any(g => g.AnimalType == ani.AnimalType && g.AnimalName == ani.AnimalName)) // 将Animal映射为Giraffe实例 .Select(ani => new Giraffe { AnimalType = ani.AnimalType, AnimalName = ani.AnimalName, legs = 4 }); giraffes.AddRange(newGiraffes);
额外说明:如果要筛选实际类型为Giraffe的元素
如果你的真实需求是从animals中筛选实际是Giraffe类型的对象添加到giraffes,那你需要先往animals中添加Giraffe实例:
// 添加Giraffe类型的对象到animals animals.Add(new Giraffe() { AnimalType = "Giraf", AnimalName = "Tall", legs = 4 }); // 此时OfType<Giraffe>()就能拿到元素 giraffes.AddRange(animals.OfType<Giraffe>());
内容的提问来源于stack exchange,提问作者Torben Nygaard
相关产品推荐
相关产品推荐

