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>
必须支持所有这些情况,所以索引器被排除在其定义之外.
[] 运算符被解析为访问属性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)
如果您的可枚举类型是如下所示的字符串,则可以使用索引
((string[])MyEnumerableStringList)[0]
Run Code Online (Sandbox Code Playgroud)