当我枚举IEnumerable两次时,Resharper抱怨Possible multiple enumerations of IEnumerable
。我知道,在某些情况下,当你枚举两次时会出现DB查询,你会得到一个异常。
我想在测试中重现这种行为。所以,我基本上想要抛出以下函数(因为有多个枚举):
private void MultipleEnumerations(IEnumerable<string> enumerable)
{
MessageBox.Show(enumerable.Count().ToString());
MessageBox.Show(enumerable.Count().ToString());
}
我应该传递给它什么?所有列表,集合等都可以使用多个枚举。 即便是这种IEnumerable也没有例外:
private IEnumerable<string> GetIEnumerable()
{
yield return "a";
yield return "b";
}
感谢。
答案 0 :(得分:3)
您可能只想要一个自定义类:
public class OneShotEnumerable<T> : IEnumerable<T>
{
private readonly IEnumerable<T> _source;
private bool _shouldThrow = false;
public OneShotEnumerable(IEnumerable<T> source)
{
this._source = source;
}
public IEnumerator<T> GetEnumerator()
{
if (_shouldThrow) throw new InvalidOperationException();
_shouldThrow = true;
return _source.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
答案 1 :(得分:2)
创建自己的实现IEnumerable<T>
的类,如果两次调用GetEnumerator()
则抛出异常(使用布尔实例字段)。
或者,创建一个使用标志字段的迭代器,以确保它不能被调用两次(枚举迭代器两次将执行整个方法两次)。
答案 2 :(得分:1)
我从John Gietzen的答案中复制的自定义类(带有一些更正)可以与扩展方法结合使用,创建一种非常简单的方法来实现这一目标。
public class OneShotEnumerable<T> : IEnumerable<T>
{
private readonly IEnumerable<T> source;
private bool shouldThrow = false;
public OneShotEnumerable(IEnumerable<T> source)
{
this.source = source;
}
public IEnumerator<T> GetEnumerator()
{
if (shouldThrow)
throw new InvalidOperationException("This enumerable has already been enumerated.");
shouldThrow = true;
return this.source.GetEnumerator();
}
}
public static clas OneShotEnumerableExtension
{
public static IEnumerable<T> SingleUse<T>(this IEnumerable<T> source)
{
#if (DEBUG)
return new OneShotEnumerableExtension(source);
#else
return source;
#endif
}
}
然后,您只需执行
即可将某些内容传递给之前的方法MultipleEnumerations(MyEnumerable.SingleUse());