Resharper:可能的IEnumerable的多个枚举
我正在使用新的Resharper版本6.在我的代码中的几个地方,它已经强调了一些文本,并警告我可能会有一个可能的IEnumerable多个枚举 。
我理解这意味着什么,并在适当的时候采纳了build议,但在某些情况下,我不确定这实际上是一个大问题。
像下面的代码一样:
var properties = Context.ObjectStateManager.GetObjectStateEntry(this).GetModifiedProperties(); if (properties.Contains("Property1") || properties.Contains("Property2") || properties.Contains("Property3")) { ... }
它强调每一个提到的properties
在第二行,警告我多次枚举这个IEnumerable。
如果将.ToList()
添加到第1行的末尾(将properties
从IEnumerable<string>
转换为List<string>
),则警告消失。
但是,如果将其转换为List,那么它将枚举整个IEnumerable来首先构buildList,然后根据需要枚举List以查找属性(即1个完全枚举和3个部分枚举)。 而在我原来的代码中,只做了3个部分枚举。
我错了吗? 这里最好的方法是什么?
我不知道你的properties
真的在这里 – 但是如果它本质上代表一个无形的数据库查询,那么你的if
语句将执行三个查询。
我怀疑这样做会更好:
string[] propertiesToFind = { "Property1", "Property2", "Property3" }; if (properties.Any(x => propertiesToFind.Contains(x)) { ... }
这在逻辑上只会遍历序列一次 – 如果涉及到数据库查询,它可能只能使用SQL“IN”子句在单个查询中在数据库中完成所有操作。
如果你调用IEnumerable上的Contains()
,它将调用扩展方法,它将遍历项目以find它。 IList
对Contains()
实际实现可能比通过值的常规迭代更有效率(它可能具有带哈希的search树?),因此它不会与IList
警告。
由于扩展方法只会意识到它是一个IEnumerable
,它可能不能使用Contains()
任何内置方法,即使在理论上可能识别已知types并相应地投射它们以便利用它们。