我有时在C#源代码中使用LINQ构造。我使用VS 2010和ReSharper。现在我从ReSharper获得“可能多次枚举IEnumerable”的警告。
我想根据最佳做法进行重构。这里简要介绍它的作用:
IEnumerable<String> codesMatching = from c in codes where conditions select c;
String theCode = null;
if (codesMatching.Any())
{
theCode = codesMatching.First();
}
if ((theCode == null) || (codesMatching.Count() != 1))
{
throw new Exception("Matching code either not found or is not unique.");
}
// OK - do something with theCode.
一个问题: 我应该首先将LINQ表达式的结果存储在List中吗? (我很确定它不会返回超过几行 - 最多说10行。)
任何提示都表示赞赏。
由于 帕维尔
答案 0 :(得分:3)
是的,您需要将结果存储为List \ Array,然后使用它。在那种情况下,它不会列举几次。
在您的情况下,如果您需要确保只有一个项目满足条件,您可以使用Single
- 如果有多个项目满足条件,它将抛出异常。如果根本没有任何物品,它也会引发异常。
您的代码会更容易:
string theCode = (from c in codes where conditions select c).Single();
但在这种情况下,您无法更改异常文本,或者您需要将其包装到自己的try \ catch块中并使用自定义文本重新抛出\ exception
答案 1 :(得分:2)
由于您要验证条件是否唯一,您可以尝试这样做(是的,您必须存储结果):
var codes = (from c in codes where conditions select c).Take(2).ToArray();
if (codes.Length != 1)
{
throw new Exception("Matching code either not found or is not unique.");
}
var code = codes[0];
答案 2 :(得分:1)
使用.ToList()
/ .ToArray()
完成可枚举将消除警告,但要了解它是否优于多个枚举将取决于codes
和conditions
实现。 .Any()
和.First()
是懒惰的原语,并且不会执行第一个元素,而.Count()
可能根本不会被命中,因此转换为列表可能比获取列表更浪费新的普查员。