1

有没有办法在同一枚举上运行的方法中引用源枚举?

例如,这段代码重复了原来的可枚举范围 1-6:

IEnumerable<int> result = Enumerable.Range(1, 6)
    .Where(a => Enumerable.Range(1, 6).Count() % 2 == 0);

我想知道是否有一种更清洁的方法可以通过重复原始枚举来生成它,例如:

IEnumerable<int> result = Enumerable.Range(1, 6)
    .Where(a => [source reference].Count() % 2 == 0);

是的,我知道以下是一个解决方案......但是有没有办法直接引用内存中的可枚举,如上所示?

IEnumerable<int> source = Enumerable.Range(1, 6);
IEnumerable<int> result = source.Where(a => source.Count() % 2 == 0);

我不是在寻找上述代码行的具体答案;他们只是展示我想知道的一个例子。

4

3 回答 3

2

没有一个内置的IEnumerable扩展方法可以做你想做的事。它们都接受仅对单个项目进行操作的 lamba 表达式,因此您的表达式无法访问父容器。

然而,没有什么能阻止你自己动手,比如:

public static IEnumerable<T> WhereSource<T> ( this IEnumerable<T> source, Func<IEnumerable<T>, T, bool> predicate)
{
  foreach (var item in source)
  {
    if (predicate(source, item))
    {
      yield return item;    
    }
  }
}

就个人而言,我认为您的原始解决方案比制作您自己的自定义扩展方法更清晰、更易于维护并且更好,但这当然是可能的。

于 2012-09-19T12:26:44.343 回答
1

你是这个意思吗?

IEnumerable<int> source = Enumerable.Range(1, 6); //{1,2,3,4,5,6}
IEnumerable<int> result = source.Where((a, i) => i % 2 == 0); //{1,3,5}
IEnumerable<int> result2 = source.Where(a => a % 2 == 0); //{2,4,6}
于 2012-09-19T12:23:17.930 回答
0

不,你不能,因为那Enumerable.Range(1, 6))没有名字。

你将如何称呼一个没有名字的实体。

您的第三个片段是您可以使用的唯一解决方案,因为它没有名称可供参考。

但是你可以做

int length = 6; // Here hard-coded but can be passed from a parameter.
IEnumerable<int> source = Enumerable.Range(1, Length);
IEnumerable<int> result = source.Where(a => length % 2 == 0);
于 2012-09-19T12:21:01.670 回答