C#linq可能的多重枚举最佳实践
我有时在C#源代码中使用LINQ构造。我使用VS2010和ReSharper。现在我从ReSharper得到了“可能多次枚举IEnumerable”警告 我想根据最佳实践重构它。下面简要介绍一下它的作用:C#linq可能的多重枚举最佳实践,c#,linq,C#,Linq,我有时在C#源代码中使用LINQ构造。我使用VS2010和ReSharper。现在我从ReSharper得到了“可能多次枚举IEnumerable”警告 我想根据最佳实践重构它。下面简要介绍一下它的作用: IEnumerable<String> codesMatching = from c in codes where conditions select c; String theCode = null; if (codesMatching.Any()) { theCode =
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.
IEnumerable codesMatching=条件选择c的代码中的c;
字符串theCode=null;
if(codesmatch.Any())
{
theCode=codesmatch.First();
}
if((theCode==null)| |(codesmatch.Count()!=1))
{
抛出新异常(“未找到匹配的代码或代码不唯一”);
}
//好的-用代码做些什么。
问题:
我应该首先将LINQ表达式的结果存储在列表中吗?
(我很确定它返回的行数不会超过几行,最多10行。)
任何提示,不胜感激
谢谢
Pavel是的,您需要将结果存储为列表\数组,然后使用它。在这种情况下,它不会列举几次 在您的情况下,如果您需要确保只有一个项目满足条件,您可以使用-如果有多个项目满足条件,它将抛出异常。若根本并没有项目,它也会抛出异常 您的代码将更容易:
string theCode = (from c in codes where conditions select c).Single();
但在这种情况下,您无法更改异常文本,或者您需要将其包装到自己的try\catch块中,并使用自定义text\exception重新播放它,因为您想验证您的条件是否唯一,您可以尝试此操作(是的,您必须存储结果):
使用
.ToList()
/.ToArray()
完成可枚举性将消除警告,但要了解它是否优于多次枚举,则取决于代码和条件的实现.Any()
和.First()
是懒惰的原语,不会超过第一个元素执行,而且.Count()
可能根本不会被命中,因此转换为列表可能比获得新的枚举数更浪费。您可以使用FirsOrDefault
或SingleOrDefault
FirstOrDefault()
将错过多个匹配的情况,但是SingleOrDefault()
会起作用。谢谢@volodymyrmelnychukb但是如果只有一个项目,并且该项目为null
,Single
不会引发异常,但OP的代码会引发异常。这通常不是问题,但值得指出的是,这不一定是替代品的减少。如果您只想阅读查询结果,也可以这样做。@hvd,是的,同意。但如果原始条件
集合中存在null
项,则会很奇怪。但是,是的,可以。我不知道单身()。很好的解决方案。我不希望结果中出现空值。所以使用Single()对我来说很好。谢谢。我想匹配有多个元素满足条件,因为您阻止使用try-catch,如果他希望条件经常返回多个值,那么try-catch更有效。谢谢,João。您的代码更简单、更清晰。
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];