C# 为什么我不能将列表添加到列表?
我有一组实现接口I的对象列表。我想把这些列表列成一个列表,并将它们作为一个单一的对象来处理。我已经尝试过创建一个列表并向其中添加我的其他列表,这在我看来是有意义的,因为我添加的列表包含实现I的对象,但编译器不允许我这样做 例如:C# 为什么我不能将列表添加到列表?,c#,.net,.net-3.5,C#,.net,.net 3.5,我有一组实现接口I的对象列表。我想把这些列表列成一个列表,并将它们作为一个单一的对象来处理。我已经尝试过创建一个列表并向其中添加我的其他列表,这在我看来是有意义的,因为我添加的列表包含实现I的对象,但编译器不允许我这样做 例如: public interface I { //stuff } public class A : I { //... } public class B : I { //... } //elsewhere public class C { List<
public interface I
{
//stuff
}
public class A : I
{
//...
}
public class B : I
{
//...
}
//elsewhere
public class C
{
List<A> ListOfA;
List<B> ListOfB;
List<List<I>> ListOfLists;
public C()
{
ListOfA = new List<A>();
ListOfB = new List<B>();
ListOfLists = new List<List<I>>();
ListOfLists.Add(ListOfA); //nope
ListOfLists.Add(ListOfB); //nope
}
}
我有两个问题,第一个是为什么不允许这种行为?第二个问题是,我如何才能实现我所追求的目标
为了澄清,当我尝试将列表添加到ListofList时,我无法从列表转换到列表,其中T:I。我使用的是.NET 3.5,不,我无法升级到更高版本。如果可以,您可以编写:
List<I> listOfAs = ListOfLists[0];
var B = new B();
listOfAs.Add(B);
这显然是禁止的,因为您不能将B实例添加到a的列表中
埃里克·利珀特(Eric Lippert)用动物而不是As和Bs给出了一个很好的类似例子
要回答您的第二个问题,我们需要执行您打算对ListofList执行的操作,只需在集合初始化后枚举或修改集合即可
如果只是想拥有I实例的只读集合:
IEnumerable<I> collectionOfIs = ListOfA.Cast<I>().Concat(ListOfB.Cast<I>());
这是因为列表实现了IEnumerable
然后,您可以使用ToList来具体化集合,并能够使用索引器:
List<I> listOfIs = collectionOfIs.ToList();
您需要使用IEnumerable,因为List是一个集合对象
List<A> ListOfA;
List<B> ListOfB;
List<IEnumerable<I>> ListOfLists;
public C()
{
ListOfA = new List<A>();
ListOfB = new List<B>();
ListOfLists = new List<IEnumerable<I>>();
ListOfLists.Add(ListOfA);
ListOfLists.Add(ListOfB);
}
说得好,但是如果我想要一个只读的、包含所有其他列表元素的串联列表呢?@Logan:那么您想要的类型是IEnumerable,而不是List。啊哈!我错过了康卡特方法。让我快速试试。@Logan您需要在您的usings@Logan如果你不想切换到.NET 4.5,并且你不想复制,那么你必须编写你自己的代码,或者考虑使用这样的东西:免责声明:我写的。它具有轻量级只读包装器类,可以动态地投影元素,即在索引元素时强制转换元素,而无需创建新列表。也就是说,在本例中,您将使用ListOfA.AsIndexable.Selecta=>Ia,它将返回可索引只读集合。尝试此操作后,无效。同样的问题,无法从列表转换为IEnumberable@Logan哥们,我也试过:|,把你的attempt@Logan:这应该适用于.NET 4.5及更新版本,因为IEnumerable的泛型类型参数已生成,即添加了out关键字:IEnumerable。这也适用于我。我使用的是.NET 3.5,请参阅我的标签:我将更新问题以进行指定。这是关于差异和设计的,您想要的东西在您的方式中是不可能的也相关:。