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行的末尾(将propertiesIEnumerable<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它。 IListContains()实际实现可能比通过值的常规迭代更有效率(它可能具有带哈希的search树?),因此它不会与IList警告。

由于扩展方法只会意识到它是一个IEnumerable ,它可能不能使用Contains()任何内置方法,即使在理论上可能识别已知types并相应地投射它们以便利用它们。