I have this foreach-loop:
foreach (var classId in m_ClassMappings[taAddressDefinition.Key])
{
if(!m_TAAddressDefinitions.ContainsKey(classId))
{
m_TAAddressDefinitions.Add(classId, taAddressDefinition.Value);
}
}
m_TAAddressDefinitions is an IDictionary where classId is used as the unique Key value.
Resharper suggests to change the if-statement into into a LINQ filter like this:
foreach (var classId in m_ClassMappings[taAddressDefinition.Key].Where(
classId => !m_TAAddressDefinitions.ContainsKey(classId)))
{
m_TAAddressDefinitions.Add(classId, taAddressDefinition.Value);
}
I am conserned if this might not work as expected, since the content of the m_TAAddressDefinitions collection is changing inside the loop, which causes the source of the LINQ filter-condition (classId => !m_TAAddressDefinitions.ContainsKey(classId)) to change on the way.
Will this fail if two classId with same value is added inside the loop, or will the LINQ condition be recalculated when values are added to the collection? My original if-statement was intended to not cause exception if the key already exist.
In this case, the fact that the
IEnumerablereturned byWherein the refactored version will lazily produce values as it is iterated over achieves what you want. The suggestion that includes theToListcall is not what you want in this case since that would materialize theIEnumerableas a collection and you would be vulnerable to there being duplicateclassIdsin them_ClassMappingscollection.The thing to remember is that the predicate in the
Wherecall, namelyclassId => !m_TAAddressDefinitions.ContainsKey(classId)will be evaluated for each item as it is produced as a result of iterating over theIEnumerable. So in the version suggested by Resharper, if there were duplicate values in them_ClassMappingsthe first one encountered would be added to them_TAAddressDefinitionsbut when the next duplicate is reached theWherepredicate will return false because the value has been previously added to the Dictionary.