I'm using the new Resharper version 6. In several places in my code it has underlined some text and warned me that there may be a Possible multiple enumeration of IEnumerable.
I understand what this means, and have taken the advice where appropriate, but in some cases I'm not sure it's actually a big deal.
Like in the following code:
var properties = Context.ObjectStateManager.GetObjectStateEntry(this).GetModifiedProperties();
if (properties.Contains("Property1") || properties.Contains("Property2") || properties.Contains("Property3")) {
...
}
It's underlining each mention of properties
on the second line, warning that I am enumerating over this IEnumerable multiple times.
If I add .ToList()
to the end of line 1 (turning properties
from a IEnumerable<string>
to a List<string>
), the warnings go away.
But surely, if I convert it to a List, then it will enumerate over the entire IEnumerable to build the List in the first place, and then enumerate over the List as required to find the properties (i.e. 1 full enumeration, and 3 partial enum开发者_如何学运维erations). Whereas in my original code, it is only doing the 3 partial enumerations.
Am I wrong? What is the best method here?
I don't know exactly what your properties
really is here - but if it's essentially representing an unmaterialized database query, then your if
statement will perform three queries.
I suspect it would be better to do:
string[] propertiesToFind = { "Property1", "Property2", "Property3" };
if (properties.Any(x => propertiesToFind.Contains(x))
{
...
}
That will logically only iterate over the sequence once - and if there's a database query involved, it may well be able to just use a SQL "IN" clause to do it all in the database in a single query.
If you invoke Contains()
on a IEnumerable, it will invoke the extension method which will just iterate through the items in order to find it. IList
has real implementation for Contains()
that probably are more efficient than a regular iteration through the values (it might have a search tree with hashes?), hence it doesn't warn with IList
.
Since the extension method will only be aware that it's an IEnumerable
, it probably can not utilize any built-in methods for Contains()
even though it would be possible in theory to identify known types and cast them accordingly in order to utilize them.
精彩评论