无法从IEnumerable <t>转换为ICollection <t> </t> </t>

时间:2012-01-01 10:48:19

标签: c# .net

我定义了以下内容:

public ICollection<Item> Items { get; set; }

当我运行此代码时:

Items = _item.Get("001");

我收到以下消息:

Error   3   
Cannot implicitly convert type 
'System.Collections.Generic.IEnumerable<Storage.Models.Item>' to 
'System.Collections.Generic.ICollection<Storage.Models.Item>'. 
An explicit conversion exists (are you missing a cast?)

有人可以解释我做错了什么。我很困惑 Enumerable,Collections和使用ToList()

之间的区别

添加信息

稍后在我的代码中,我有以下内容:

for (var index = 0; index < Items.Count(); index++) 

我可以将Items定义为IEnumerable吗?

3 个答案:

答案 0 :(得分:90)

ICollection<T>继承自IEnumerable<T>,因此要分配

的结果
IEnumerable<T> Get(string pk)

ICollection<T>有两种方式。

// 1. You know that the referenced object implements `ICollection<T>`,
//    so you can use a cast
ICollection<T> c = (ICollection<T>)Get("pk");

// 2. The returned object can be any `IEnumerable<T>`, so you need to 
//    enumerate it and put it into something implementing `ICollection<T>`. 
//    The easiest is to use `ToList()`:
ICollection<T> c = Get("pk").ToList();

第二种选择更灵活,但性能影响更大。另一种选择是将结果存储为IEnumerable<T>,除非您需要ICollection<T>接口添加的额外功能。

其他表现评论

你拥有的循环

for (var index = 0; index < Items.Count(); index++)

适用于IEnumerable<T>,但效率低下;每次调用Count()都需要完整枚举所有元素。使用集合和Count属性(不带括号)或将其转换为foreach循环:

foreach(var item in Items)

答案 1 :(得分:26)

您无法直接从IEnumerable<T>转换为ICollection<T>。您可以使用ToList IEnumerable<T>方法将其转换为ICollection<T>

someICollection = SomeIEnumerable.ToList();

答案 2 :(得分:1)

有关该问题的更多信息:

请提供有关项目类型和Get

签名的更多信息

您可以尝试两件事:

  • 将_item.Get的返回值转换为(ICollection)
  • 其次使用_item.Get(“001”)。ToArray()或_item.Get(“001”)。ToList()

请注意第二个会导致阵列副本的性能损失。如果Get的签名(返回类型)不是ICollection,那么第一个将不起作用,如果它不是IEnumerable则第二个将不起作用。


在您澄清问题和评论之后,我会亲自向ICollection声明_item.Get(“001”)的返回类型。这意味着您不必进行任何转换或转换(通过ToList / ToArray),这将涉及不必要的创建/复制操作。

// Leave this the same
public ICollection<Item> Items { get; set; }

// Change function signature here:
// As you mention Item uses the same underlying type, just return an ICollection<T>
public ICollection<Item> Get(string value); 

// Ideally here you want to call .Count on the collectoin, not .Count() on 
// IEnumerable, as this will result in a new Enumerator being created 
// per loop iteration
for (var index = 0; index < Items.Count(); index++) 

致以最诚挚的问候,