无法将带有[]的索引应用于类型为"System.Collections.Generic.IEnumerable <>的表达式"

San*_*eep 61 c# generics ienumerable

IEnumerable中是否允许索引是否有任何特定原因.

我找到了解决问题的方法,但只是想知道它为什么不允许索引.

谢谢,

Jam*_*ran 70

因为事实并非如此.

索引包含在内IList. IEnumerable意思是"我拥有IList的一些权力,但不是所有权力."

某些集合(如链接列表)无法以实用方式编制索引.但是可以逐项访问它们. IEnumerable适用于那样的集合.请注意,集合可以实现IList和IEnumerable(以及许多其他).您通常只能找到IEnumerable一个函数参数,这意味着该函数可以接受任何类型的集合,因为它所需要的只是最简单的访问模式.


Ani*_*Ani 45

IEnumerable<T>接口不包括索引,你可能与它混淆IList<T>

如果对象确实是IList<T>(例如List<T>或数组T[]),请尝试对类型进行引用IList<T>.

否则,您可以使用myEnumerable.ElementAt(index) 它使用Enumerable.ElementAt扩展方法.这适用于所有人IEnumerable<T>.请注意,除非(运行时)对象实现IList<T>,否则将导致index + 1枚举所有第一个项目,除了最后一个项目之外的所有项目都将被丢弃.

编辑:作为解释,IEnumerable<T>只是一个代表"暴露枚举器的那个"的接口.具体实现可能是某种内存列表,允许通过索引快速访问,或者它可能不允许.例如,它可能是一个无法有效满足这种查询的集合,例如链表(如James Curran所述).它甚至可能根本不是内存中的数据结构,例如迭代器,按需生成("生成")项,或者是从某些远程数据源获取项的枚举器.因为IEnumerable<T>必须支持所有这些情况,所以索引器被排除在其定义之外.

  • @chilltemp:我提到过这一点。 (2认同)
  • 值得注意的是,`ElementAt` 的实现足够智能,可以检查对象是否可以转换为 `IList`,如果可以,则直接索引而不是逐项遍历。 (2认同)
  • myEnumerable.ElementAt(index) 帮助了我。谢谢! (2认同)

Lor*_*uer 6

[] 运算符被解析为访问属性this[sometype index],其实现取决于元素集合

Enumerable-Interface首先声明了Collection 应该是什么样子的蓝图。

以此示例来演示干净的接口分离的用处:

var ienu = "13;37".Split(';').Select(int.Parse);
//provides an WhereSelectArrayIterator
var inta = "13;37".Split(';').Select(int.Parse).ToArray()[0];
//>13
//inta.GetType(): System.Int32
Run Code Online (Sandbox Code Playgroud)

另请查看[] 运算符的语法

  //example
public class SomeCollection{
public SomeCollection(){}

 private bool[] bools;

  public bool this[int index] {
     get {
        if ( index < 0 || index >= bools.Length ){
           //... Out of range index Exception
        }
        return bools[index];
     }
     set {
        bools[index] = value;
     }
  }
//...
}
Run Code Online (Sandbox Code Playgroud)

  • 得票较高的答案可能是正确的,但我发现这个评论在我自己的场景中更有帮助(这与原始帖子没有什么不同)。谢谢! (2认同)

Cod*_*orm 6

如果您的可枚举类型是如下所示的字符串,则可以使用索引

((string[])MyEnumerableStringList)[0]
Run Code Online (Sandbox Code Playgroud)


Don*_*nal 5

您可以使用ToList转换为列表。例如,

SomeItems.ToList()[1]
Run Code Online (Sandbox Code Playgroud)