即使是“IsNullOrEmpty”检查给出“IEnumerable 的可能多重枚举”警告
已经有一个关于“可能的多重枚举”的问题,但这个问题更具体。
请考虑以下方法,该方法采用 IEnumerable
作为输入,并对其每个元素执行给定的方法:
public static bool SomeMethod(IEnumerable<string> enumerable)
{
if (enumerable.IsNullOrEmpty())
{
// throw exception.
}
else
{
return (enumerable.All(SomeBooleanMethod));
}
}
在上面的代码中,IsNullOrEmpty
只是一个扩展 问题是
return (!ReferenceEquals(enumerable, null) || enumerable.Any());
ReSharper 警告我“可能存在多个 IEnumerable 枚举”,我真的不知道这是否真的是一个问题。
我理解警告的含义,但是如果您确实需要检查并在空或空的情况下抛出异常,那么在这种情况下您真正能做什么?
There's a question on SO about "possible multiple enumerations" already, but this question is more specific.
Please consider the following method, which takes an IEnumerable<string>
as input and executes a given method against each of its elements:
public static bool SomeMethod(IEnumerable<string> enumerable)
{
if (enumerable.IsNullOrEmpty())
{
// throw exception.
}
else
{
return (enumerable.All(SomeBooleanMethod));
}
}
In the code above, IsNullOrEmpty
is just an extension method which runs
return (!ReferenceEquals(enumerable, null) || enumerable.Any());
The problem is that ReSharper is warning me about "Possible multiple enumerations of IEnumerable", and I really don't know if this can actually be a problem or not.
I understand the meaning of the warning, but what could you really do in this situation if you really need to check and throw exception in case of nullity or emptyness?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这意味着您(部分)多次迭代 IEnumerable:首先在调用
Any()
时(它至少需要初始化一次迭代以查看可枚举是否返回任何元素),第二次在All
中(从头开始迭代)。ReSharper 警告您这一点的原因是,枚举可枚举可能会导致副作用,并且无意中迭代两次可能会触发两次副作用,这可能是理想的,也可能不是理想的。
It means that you are (partially) iterating over the IEnumerable more than once: first in your call to
Any()
(which needs to at least initialize an iteration to see if the enumerable returns any elements), and a second time inAll
(which iterates from the beginning).The reason ReSharper warns you about this is that enumerating over an enumerable may cause side effects, and unintentionally iterating twice may trigger the side effects twice, which may or may not be desirable.
正如 @tdammers 所指出的,所指的“多个枚举”是
Any
和All
所需的两个枚举。既然你想拒绝一个空序列,我能想到的最好的办法是:As @tdammers identifies, the "multiple enumerations" referred to are the two enumerations required by
Any
andAll
. Since you want to reject an empty sequence, the best I can come up with is:虽然这里的其他答案是正确的,因为您枚举了两次(以及这样做的潜在危害),但对于您收到警告的原因,它们都(微妙地)不正确。
Resharper 不会警告您,因为您正在调用
Any()
和All()
。它警告您,因为您正在调用IsNullOrEmpty()
和All()
。事实上,Resharper 甚至不知道您正在调用Any()
。尝试删除它 - 您会发现您仍然收到警告。这是因为 Resharper 不知道传递给另一个方法的可枚举会发生什么。也许其他方法会枚举它,也许不会。但是您将枚举传递给两个方法,所以也许它们都枚举它,所以也许它被枚举两次。因此,警告“可能多重枚举”。
这很微妙但很重要。在您的情况下,警告很有用,因为您枚举了两次。但也许您的扩展方法不枚举可枚举项,并且您知道可以忽略该警告。在这种情况下,Resharper 会为您提供
NoEnumeration
Resharper 代码注释中的属性这允许您标记枚举,如下所示 。配制方法如下:
Whilst the other answers here are correct in that you are enumerating twice (and the potential harm in doing so), they are both (subtly) incorrect as to why you are getting the warning.
Resharper is not warning you because you are calling
Any()
andAll()
. It is warning you because you are callingIsNullOrEmpty()
andAll()
. In fact, Resharper doesn't even know you are callingAny()
.Try removing it - you will find you still get the warning.This is because Resharper has no idea what happens to an enumerable which is passed to another method. Maybe that other method enumerates it, maybe not. But you are passing the enumerable to two methods, so maybe they both enumerate it, so maybe it is enumerated twice. Hence the warning, "Possible multiple enumeration'.
This is subtle but important. In your case, the warning was useful, because you were enumerating twice. But maybe your extension method doesn't enumerate the enumerable and you know the warning can be ignored. In this case, Resharper provides you with the
NoEnumeration
attribute in Resharper's Code Annotations.This allows you to tag an enumerable, as in the following made up method: