C#linq可能有多个枚举最佳实践

时间:2014-05-20 09:41:00

标签: c# linq

我有时在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行。)

任何提示都表示赞赏。

由于 帕维尔

3 个答案:

答案 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()完成可枚举将消除警告,但要了解它是否优于多个枚举将取决于codesconditions实现。 .Any().First()是懒惰的原语,并且不会执行第一个元素,而.Count()可能根本不会被命中,因此转换为列表可能比获取列表更浪费新的普查员。