将数组转换为ICollection<T>

16
什么是在C#中从T[]转换为ICollection的最佳方法?

10
一个类型为 T 的数组实现了 ICollection<T> 接口,没有进行转换。 - Thorarin
2
数组不安全地实现了 ICollection<T> 接口 - 请参见答案 - sinelaw
3个回答

41

数组 T 可以赋值给 TICollection,因为 T 的数组实现了 TIListTIList 本身扩展了 TICollection,所以你可以直接将一个数组赋值给 ICollection

class Foo {}

Foo [] foos = new Foo [12];
ICollection<Foo> foo_collection = foos;

你是说,基本上不需要进行转换,因为Array已经是一个ICollection了? - Mołot
无法将数组Foo[]转换为ICollection。 - Burre Ifort

28

简短回答:

使用 ToList()。除非您知道以下内容并且知道自己在做什么,否则不要依赖于将T[]分配给ICollection<T>

如果您需要只读,则最好使用Array.AsReadOnly(T[])来避免额外的拷贝,并避免下面详细讨论的问题。


详细回答:

尽管 T 数组(即 T[]技术上实现了IList<T> (以及ICollection<T>IEnumerable<T>),但是它并没有完全实现IList<T>ICollection<T>接口,正如文档中所述

...当你将数组强制转换为这些接口之一时,要注意的关键事项是添加、插入或删除元素的成员会引发NotSupportedException异常。

换句话说,如果你只是将数组强制转换为ICollection<T>,则在调用任何上述方法时会立即获得NotSupportedException异常。

因此,将数组安全地转换为ICollection<T>的最佳方法是创建一个新对象,例如使用LinqToList()

T[] array;

// Will create a new list based on the current contents of the array
ICollection<T> collection = array.ToList();

3
这是更好的答案,被接受的回答并没有真正提到在不小心转换时的“危险”。 - Rudi Visser
如果我知道我不会修改集合,那么将 ICollection<T> 强制转换是否安全? - Daniel Lorenz
我不想创建新的东西,因为当数组中有很多项时,开始会有开销。@sinelaw - Daniel Lorenz
@DanielLorenz 我认为AsReadOnly没有太大的开销,它只是包装了现有的数组(根据我链接的文档)。 - sinelaw
@sinelaw 嗯...这需要实验! - Daniel Lorenz
显示剩余2条评论

0
除了答案和评论之外,如果你想要另一种方式,你可以在 IEnumerable 上使用 ToArray() 方法(ICollection 是它的子类)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接