Linq Any()副作用 [英] Linq Any() side effects

查看:153
本文介绍了Linq Any()副作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果反射器正确(我倾向于认为是正确的),则这是Any()的实现:

If reflector is right (and I tend to believe it is), this is the implementation for Any():

public static bool Any<TSource>(this IEnumerable<TSource> source) {
        if (source == null) throw Error.ArgumentNull("source");
        using (IEnumerator<TSource> e = source.GetEnumerator()) {
            if (e.MoveNext()) return true;
        }
        return false;
    }

根据我的理解,MoveNext()将基础枚举数移动一个位置,因此,多次调用Any()会对缩小"集合产生不利影响.

From my understanding, MoveNext() moves the underlying enumerator by one position and therefore, calling Any() multiple times can have an adverse effect on "shrinking" the collection.

我试图用List<>重现此内容,但是我却无法做到这一点,但是,我无法找出List<>在解决此问题上有何不同之处.

I tried to reproduce this with a List<> but I wasn't able to do this, yet, I'm unable to find out what List<> does differently to address this problem.

我用来验证List<T>的简单示例可以在多个Any()调用中正常工作:

My simple example to verify List<T> works correctly with multiple Any() calls:

var meh = new List<string> {"1", "2"};
var enumerable = meh.AsEnumerable();
bool any = enumerable.Any(); //true
any = enumerable.Any(); //true
any = enumerable.Any(); //true but isn't it meant to have "moved" the enumerator by two positions already?
any = enumerable.Any(); //true

所以我的问题是:

  1. 我正确理解Any()确实对Enumerable有副作用
  2. 如果是,List<>如何规避它?
  1. Am I correct in understanding that Any() does indeed have side effects on the Enumerable
  2. If so, how does List<> circumvent it?

很抱歉,如果您事先提出了一个愚蠢的问题.只是我发现很有趣的东西.

Sorry if it's a dumb question in advance. Just something that I found very interesting.

推荐答案

由于使用了using语句,因此枚举器被放置了,所以它总是从头开始.枚举数也总是从source.GetEnumerator()创建,并且不被重用.实际上,这是.NET源,您可以在这里.

Due to the using statement the enumerator is disposed, so it always starts at the beginning. The enumerator is also always created from source.GetEnumerator() and not reused. Actually this is the .NET source as you can see here.

它枚举序列,直到谓词匹配为止,然后将其处置.

It enumerates the sequence until the predicate matches, then it will be disposed.

此方法也不使用延迟执行(它缺少yield关键字).因此,它总是立即执行.

This method is also not using deferred execution(it lacks the yield keyword). Therefore it is always executed immediately.

这篇关于Linq Any()副作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆