IEnumerable泛型的扩展
本文关键字:扩展 泛型 IEnumerable | 更新日期: 2023-09-27 18:15:30
IEnumerable有两个扩展:
public static class IEnumerableGenericExtensions
{
public static IEnumerable<IEnumerable<T>> InSetsOf<T>(this IEnumerable<T> source, int max)
{
List<T> toReturn = new List<T>(max);
foreach (var item in source)
{
toReturn.Add(item);
if (toReturn.Count == max)
{
yield return toReturn;
toReturn = new List<T>(max);
}
}
if (toReturn.Any())
{
yield return toReturn;
}
}
public static int IndexOf<T>(this IEnumerable<T> source, Predicate<T> searchPredicate)
{
int i = 0;
foreach (var item in source)
if (searchPredicate(item))
return i;
else
i++;
return -1;
}
}
然后我写这段代码:
Pages = history.InSetsOf<Message>(500);
var index = Pages.IndexOf(x => x == Pages.ElementAt(0));
,public类History: IEnumerable但结果我得到的不是我预期的" 0 "而是" -1 "我不明白——为什么?
当你写Pages.IndexOf(x => x == Pages.ElementAt(0));
时,你实际上运行InSetsOf
很多次,由于延迟执行(又名懒惰)。扩大:
-
Pages = history.InSetsOf<Message>(500)
-这行根本不运行InSetsOf
-
Pages.IndexOf
-在Pages
上迭代,所以它开始执行InSetsOf
一次。 -
x == Pages.ElementAt(0)
-再次执行InSetsOf
,对Pages
集合中的每个元素执行一次(或者至少直到searchPredicate
返回true,这在这里不会发生)。
每次运行InSetsOf
时,您都会创建一个新列表(具体来说,是一个新的第一个列表,因为您使用ElementAt(0)
)。这是两个不同的对象,因此==
在它们之间的比较失败。
Pages
就不是一个延迟的查询,而是一个具体的集合:
Pages = history.InSetsOf<Message>(500).ToList();
另一种选择是使用SequenceEqual
,尽管我建议缓存第一个元素:
Pages = history.InSetsOf<Message>(500);
var firstPage = Pages.FirstOrDefault();
var index = Pages.IndexOf(x => x.SequenceEqual(firstPage));
你的类T实现了IComparable吗?如果不是,你的相等性检查可能是有缺陷的,因为框架不知道T= T的确切时间。我猜你也可以通过在你的类T上重写等号来获得。