Ros*_*oss 37 c# linq resharper optimization ienumerable
我正在使用新的Resharper版本6.在我的代码中的几个地方它强调了一些文本,并警告我可能有一个可能的多个IEnumerable枚举.
我理解这意味着什么,并在适当的时候采纳了建议,但在某些情况下,我不确定这实际上是一个大问题.
如下面的代码所示:
var properties = Context.ObjectStateManager.GetObjectStateEntry(this).GetModifiedProperties();
if (properties.Contains("Property1") || properties.Contains("Property2") || properties.Contains("Property3")) {
...
}
Run Code Online (Sandbox Code Playgroud)
它强调properties
了第二行的每一个提及,警告我多次枚举这个IEnumerable.
如果我添加.ToList()
到第1行的末尾(properties
从a IEnumerable<string>
转到a List<string>
),警告就会消失.
但可以肯定的是,如果我将它转换为List,那么它将枚举整个IEnumerable以首先构建List,然后根据需要枚举List以查找属性(即1个完整枚举和3个部分枚举) ).而在我的原始代码中,它只执行3个部分枚举.
我错了吗?这里最好的方法是什么?
Jon*_*eet 41
我不知道你到底在properties
究竟是什么- 但如果它本质上代表一个非物质化的数据库查询,那么你的if
语句将执行三个查询.
我怀疑这样做会更好:
string[] propertiesToFind = { "Property1", "Property2", "Property3" };
if (properties.Any(x => propertiesToFind.Contains(x))
{
...
}
Run Code Online (Sandbox Code Playgroud)
这将逻辑上只迭代序列一次 - 如果涉及数据库查询,它可能只能使用SQL"IN"子句在单个查询中在数据库中完成所有操作.
如果Contains()
在IEnumerable上调用,它将调用扩展方法,该方法将遍历项目以便找到它.IList
有真正的实现Contains()
可能比通过值的常规迭代更有效(它可能有一个带有哈希的搜索树?),因此它没有警告IList
.
由于扩展方法只知道它是一个IEnumerable
,它可能不能利用任何内置方法,Contains()
即使理论上可以识别已知类型并相应地转换它们以便利用它们.