甚至“IsNullOrEmpty”检查也会给出“可能多次枚举IEnumerable”的警告

关于“可能存在多个枚举”的SO有一个问题 ,但这个问题更具体。

请考虑以下方法,该方法将IEnumerable作为输入并对其每个元素执行给定方法:

 public static bool SomeMethod(IEnumerable enumerable) { if (enumerable.IsNullOrEmpty()) { // throw exception. } else { return (enumerable.All(SomeBooleanMethod)); } } 

在上面的代码中, IsNullOrEmpty只是一个运行的扩展方法

 return (!ReferenceEquals(enumerable, null) || enumerable.Any()); 

问题是ReSharper警告我“IEnumerable的可能的多个枚举”,我真的不知道这是否真的是一个问题。

我理解警告的含义,但是如果你确实需要在无效或空洞的情况下检查并抛出exception,那么在这种情况下你真的能做些什么呢?

这意味着你(部分地)在IEnumerable上多次迭代:首先在你对Any()调用中(它需要至少初始化迭代以查看枚举是否返回任何元素),以及第二次在All (从头开始迭代)。

ReSharper对此提出警告的原因是,对可枚举的枚举可能会导致副作用,无意中迭代两次可能会触发两次副作用,这可能是也可能不是。

正如@tdammers所指出的那样,所提到的“多个枚举”是AnyAll所需的两个枚举。 既然你想拒绝一个空序列,我能想到的最好的是:

 public static bool SomeMethod(IEnumerable enumerable) { if (enumerable == null) throw new ArgumentNullException(); // Manually perform an All, keeping track of if there are any elements bool anyElements = false; bool result = true; foreach (string item in enumerable) { anyElements = true; result = result && SomeBooleanMethod(item); // Can short-circuit here if (!result) break; } if (!anyElements) throw new ArgumentException(); // Empty sequence is invalid argument return result; }