c# - query - Resharper: posible enumeración múltiple de IEnumerable
linq performance (2)
No sé exactamente cuáles son sus properties
realmente, pero si esencialmente representa una consulta de base de datos no materializada, su instrucción if
realizará tres consultas.
Sospecho que sería mejor hacer:
string[] propertiesToFind = { "Property1", "Property2", "Property3" };
if (properties.Any(x => propertiesToFind.Contains(x))
{
...
}
Eso lógicamente solo iterará sobre la secuencia una vez, y si hay una consulta de base de datos involucrada, es muy posible que solo pueda usar una cláusula SQL "IN" para hacerlo todo en la base de datos en una sola consulta.
Estoy usando la nueva versión 6 de Resharper. En varios lugares de mi código, ha subrayado algunos textos y me ha advertido que puede haber una enumeración múltiple posible de IEnumerable .
Entiendo lo que esto significa, y he seguido el consejo cuando corresponde, pero en algunos casos no estoy seguro de que sea realmente un gran problema.
Como en el siguiente código:
var properties = Context.ObjectStateManager.GetObjectStateEntry(this).GetModifiedProperties();
if (properties.Contains("Property1") || properties.Contains("Property2") || properties.Contains("Property3")) {
...
}
Está subrayando cada mención de properties
en la segunda línea, advirtiendo que estoy enumerando este IEnumerable varias veces.
Si agrego .ToList()
al final de la línea 1 (convirtiendo properties
de una IEnumerable<string>
a una List<string>
), las advertencias desaparecen.
Pero seguramente, si lo convierto en una lista, enumerará todo el IEnumerable para compilar la lista en primer lugar y luego enumerará la lista según sea necesario para encontrar las propiedades (es decir, 1 enumeración completa y 3 enumeraciones parciales). ) Mientras que en mi código original, solo está haciendo las 3 enumeraciones parciales.
¿Me equivoco? ¿Cuál es el mejor método aquí?
Si invoca Conins Contains()
en un IEnumerable, invocará el método de extensión que simplemente recorrerá los elementos para encontrarlo. IList
tiene una implementación real para Contains()
que probablemente sea más eficiente que una iteración regular a través de los valores (puede tener un árbol de búsqueda con hashes?), Por lo que no advierte con IList
.
Dado que el método de extensión solo sabrá que es un IEnumerable
, probablemente no pueda utilizar ningún método incorporado para Contains()
aunque en teoría sería posible identificar los tipos conocidos y emitirlos en consecuencia para utilizarlos.