Enumerable.ElementAt 的重点是什么?
IEnumerable
公开了一个枚举器,因此可以枚举该对象。 此接口公开的索引没有任何内容。 IList
与索引有关,因为它公开了IndexOf
方法。
那么Enumerable.ElementAt的重点是什么? 我刚刚阅读了这个LINQ扩展方法的文档 :
返回序列中指定索引处的元素。
嗯,是的,这是一个序列 ,而不仅仅是一个IEnumerable
。 阅读评论:
如果源类型实现IList,则该实现用于获取指定索引处的元素。 否则,此方法获取指定的元素。
好的,所以如果具体类型实现了从IList
(这是一个实际序列)inheritance的东西,那么它与IndexOf()
相同。 如果不是,则迭代直到达到索引。
这是一个示例场景:
// Some extension method exposed by a lib // I know it's not a good piece of code, but let's say it's coded this way: public static class EnumerableExtensions { // Returns true if all elements are ordered public static bool IsEnumerableOrdered(this IEnumerable value) { // Iterates over elements using an index for (int i = 0; i value.ElementAt(i + 1)) { return false; } } return true; } } // Here's a collection that is enumerable, but doesn't always returns // its objects in the same order public class RandomAccessEnumerable : IEnumerable { private List innerList; private static Random rnd = new Random(); public RandomAccessEnumerable(IEnumerable list) { innerList = list.ToList(); } public IEnumerator GetEnumerator() { var listCount = this.innerList.Count; List enumeratedIndexes = new List(); for (int i = 0; i < listCount; i++) { int randomIndex = -1; while (randomIndex < 0 || enumeratedIndexes.Contains(randomIndex)) { randomIndex = rnd.Next(listCount); } enumeratedIndexes.Add(randomIndex); yield return this.innerList[randomIndex]; } } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } // Here's some test program internal class Program { private static void Main() { var test0 = new List { 0, 1, 2, 3 }; var test1 = new RandomAccessEnumerable(test0); Console.WriteLine("With List"); Console.WriteLine(test0.IsEnumerableOrdered()); // true Console.WriteLine(test0.IsEnumerableOrdered()); // true Console.WriteLine(test0.IsEnumerableOrdered()); // true Console.WriteLine(test0.IsEnumerableOrdered()); // true Console.WriteLine(test0.IsEnumerableOrdered()); // true Console.WriteLine("With RandomAccessEnumerable"); Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false Console.WriteLine(test1.IsEnumerableOrdered()); // might be true or false Console.Read(); } }
因此,由于RandomAccessEnumerable
可能以随机顺序返回枚举对象,因此您不能依赖简单的IEnumerable
接口来假设您的元素已编入索引。 因此,您不希望将ElementAt
用于IEnumerable
。
在上面的例子中,我认为IsEnumerableOrdered
应该需要一个IList
参数,因为它意味着元素是一个序列。 我实际上找不到ElementAt
方法有用的场景,而且不容易出错。
有许多IEnumerable
类型,如数组或列表。 所有IList
类型( Array
也实现)都有一个索引器 ,您可以使用它来访问特定索引处的元素。
如果序列可以成功转换为IList
,则Enumerable.ElementAt
将使用此方法。 否则将被列举。
所以它只是一种方便的方法来访问所有IEnumerable
类型的给定索引的元素。
这样做的好处是您可以在以后更改类型而无需更改arr[index]
。
对于它的价值,这里是反映(ILSpy)方法来certificate我所说的:
上述就是C#学习教程:Enumerable.ElementAt 的重点是什么?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
public static TSource ElementAt(this IEnumerable source, int index) { if (source == null) { throw Error.ArgumentNull("source"); } IList list = source as IList ; if (list != null) { return list[index]; } if (index < 0) { throw Error.ArgumentOutOfRange("index"); } TSource current; using (IEnumerator enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { if (index == 0) { current = enumerator.Current; return current; } index--; } throw Error.ArgumentOutOfRange("index"); } return current; }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/998968.html