C# i收集<;T>;不基于索引,但存在TakeWhile()
我试图将C# i收集<;T>;不基于索引,但存在TakeWhile(),c#,.net,collections,C#,.net,Collections,我试图将T[]或List的用法作为函数参数和返回值替换为更合适的类型,如IEnumerable、ICollection和IList 据我理解,ICollection比IList更可取,因为它只需要基本/简单的收集功能(例如枚举器和计数功能),因为它提供的限制最少。从这里开始阅读,我认为一个主要的区别是,ICollection不要求基础集合基于索引,而IList需要这样做 在切换我的List引用时,我需要替换一个List.GetRange()调用,我非常惊讶地发现ICollection.TakeW
T[]
或List
的用法作为函数参数和返回值替换为更合适的类型,如IEnumerable
、ICollection
和IList
据我理解,ICollection
比IList
更可取,因为它只需要基本/简单的收集功能(例如枚举器和计数功能),因为它提供的限制最少。从这里开始阅读,我认为一个主要的区别是,ICollection
不要求基础集合基于索引,而IList
需要这样做
在切换我的List
引用时,我需要替换一个List.GetRange()
调用,我非常惊讶地发现ICollection.TakeWhile()
扩展方法有一个重载支持基于索引的选择
我不明白为什么这个方法存在于ICollection上,而没有基于这个接口的索引?我是否误解了,或者如果底层集合是哈希集或其他什么,那么这个方法实际上是如何工作的?该方法与大多数LINQ一样,是在
IEnumerable
上的。任何只将索引器传递给使用者的功能(如TakeWhile
)只需在递增计数器时循环即可。一些API可能能够使用索引器进行优化,然后由它们决定是否这样做,或者只是使用IEnumerable
并简单地跳过(等)不需要的数据
例如:
int i = 0;
foreach(var item in source) {
if(!predicate(i++, item)) break;
yield return item;
}
与大多数LINQ一样,该方法位于
IEnumerable
上。任何只将索引器传递给使用者的功能(如TakeWhile
)只需在递增计数器时循环即可。一些API可能能够使用索引器进行优化,然后由它们决定是否这样做,或者只是使用IEnumerable
并简单地跳过(等)不需要的数据
例如:
int i = 0;
foreach(var item in source) {
if(!predicate(i++, item)) break;
yield return item;
}
索引可以在集合不支持的情况下完成
int i = -1;
foreach(var item in collection)
{
i++;
// item is at index i;
}
索引可以在集合不支持的情况下完成
int i = -1;
foreach(var item in collection)
{
i++;
// item is at index i;
}
类中的其他扩展方法在所有实现的类型上工作。它们都迭代集合(使用foreach
语句)并执行适当的操作
以下是TakeWhile
方法的实现,并进行了一些简化:
private static IEnumerable<TSource> TakeWhile<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
foreach (TSource item in source)
{
if (!predicate(item))
{
break;
}
yield return item;
}
}
private静态IEnumerable TakeWhile(IEnumerable源,Func谓词)
{
foreach(源中的TSource项)
{
if(!谓词(项))
{
打破
}
收益回报项目;
}
}
如您所见,它只是在集合上迭代,并计算谓词。这几乎适用于所有其他LINQ方法。当您使用任何其他集合(如HashSet
和类中的其他扩展方法)处理所有实现的类型时,也会发生同样的情况。它们都迭代集合(使用foreach
语句)并执行适当的操作
以下是TakeWhile
方法的实现,并进行了一些简化:
private static IEnumerable<TSource> TakeWhile<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
foreach (TSource item in source)
{
if (!predicate(item))
{
break;
}
yield return item;
}
}
private静态IEnumerable TakeWhile(IEnumerable源,Func谓词)
{
foreach(源中的TSource项)
{
if(!谓词(项))
{
打破
}
收益回报项目;
}
}
如您所见,它只是在集合上迭代,并计算谓词。这几乎适用于所有其他LINQ方法。当您使用任何其他集合(如HashSet
)时,也会发生同样的情况