如何分配列表<;熊>;或者List<;山羊>;到列表<;IAnimal>;
本文关键字:gt lt 列表 List 或者 山羊 IAnimal 何分配 分配 | 更新日期: 2023-09-27 18:25:20
我有一个接口(IAnimal
),它由Bear和Goat两个类实现。
在运行时,我可能会得到一个Bears或Goats列表,但无论是哪一个,都需要将它们分配给属性IEnumerable<IAnimal>
这是有效的,因为IEnumerable
是共变体。
但是,我现在需要从IEnumerable<IAnimal>
中删除项目,这当然不起作用。
我需要做什么才能删除项目?
这是工作样本:
interface IAnimal {}
public class Bear : IAnimal {}
public class Goat : IAnimal {}
class Program
{
public static IEnumerable<IAnimal> CouldBeBearsOrGoats { get; set; }
static void Main(string[] args) {
var list = new List<int>() {1, 2, 3};
var bears = from l in list select new Bear();
var goats = from l in list select new Goat();
CouldBeBearsOrGoats = bears;
CouldBeBearsOrGoats = goats;
//How do I now remove an item?
}
}
如果我将CouldByearsOrGoats更改为List,那么我可以删除项目,但不能再分配任何一种类型。
public static List<IAnimal> CouldBeBearsOrGoats { get; set; }
这个列表会很长,所以我不想只复制列表并使用副本。我正在做的是处理列表中的每个项目,然后将其删除,直到列表为空。
由于源数据无论如何都是IEnumerable的,因此必须将其转换为List才能添加/删除元素。
List<IAnimal> ListOfAnimals1 = bears.Cast<IAnimal>().ToList();
List<IAnimal> ListOfAnimals2 = goats.Cast<IAnimal>().ToList();
一种可能性是在LINQ查询中添加一个Cast
调用,这样它就可以将IEnumerable<Goat>
转换为IEnumerable<IAnimal>
(这实际上会为每个元素创建一个新的迭代器)。
var bears = (from l in list select new Bear()).Cast<IAnimal>().ToList();
var goats = (from l in list select new Goat()).Cast<IAnimal>().ToList();
现在bears
和goats
都是IAnimal
的可枚举项,您可以对它们进行操作。
我认为没有一种简单的方法可以只使用强类型集合来实现这一点1,因为没有公开Remove
方法的协变集合接口。。。
我看到了两种可能的解决方案:
-
使用由
List<T>
:实现的非通用ICollection
接口var collection = (ICollection) CouldBeBearsOrGoats; collection.Remove(whatever);
缺点是实现
ICollection<T>
的集合可能无法实现ICollection
。。。 -
使用动态:
dynamic collection = CouldBeBearsOrGoats collection.Remove(whatever);
但它可能比以前的方法慢。
1假设您不想通过将项强制转换为IAnimal
来更改集合的实际类型