我写了以下代码:
IEnumerable<string> blackListCountriesCodes =
pair.Criterion.CountriesExceptions.Select(countryItem => countryItem.CountryCode);
IEnumerable<string> whiteListCountriesCodes =
pair.Criterion.Countries.Select(countryItem => countryItem.CountryCode);
return (!blackListCountriesCodes.Contains(Consts.ALL.ToString()) &&
!blackListCountriesCodes.Contains(country) &&
(whiteListCountriesCodes.Contains(Consts.ALL.ToString()) ||
whiteListCountriesCodes.Contains(country)));
resharper给我一个警告:
Possible duplicate enumeration of IEnumerable
这是什么意思?为什么这是一个警告?
答案 0 :(得分:8)
LINQ查询推迟执行,直到您对结果执行某些操作。在这种情况下,在同一个集合上调用Contains()
两次可能会导致结果被枚举两次,这取决于查询,可能会导致性能问题。
您可以通过简单地在查询结尾处添加ToList()
调用来解决此问题,该调用将强制执行查询并将结果存储一次。
答案 1 :(得分:1)
这意味着您的代码可能会多次枚举blackListCountriesCodes
和whiteListCountriesCodes
。由于LINQ使用延迟评估,这可能会导致速度变慢,尤其是当pair
包含大量数据时,Where
子句很复杂(尽管如此,它看起来并不适用于任何情况)。
您可以通过将枚举“实现”到列表中来消除警告(以及所谓的缓慢),如下所示:
var blackListCountriesCodes =
pair.Criterion.CountriesExceptions.Select(countryItem => countryItem.CountryCode).ToList();
var whiteListCountriesCodes =
pair.Criterion.Countries.Select(countryItem => countryItem.CountryCode).ToList();
答案 2 :(得分:1)
这意味着您可以计算IEnumerable
两次(或更多)的内容。如果这很昂贵,就像调用数据库一样,这对性能不利。如果底层来源是List<T>
并且有一个简单的投影或其他不昂贵的东西,这不是问题。
你当然可以重写表达式只使用一次枚举。
!blackListCountriesCodes.Contains(Consts.ALL.ToString())
&& !blackListCountriesCodes.Contains(country)
可以改写为
!blackListCountriesCodes
.Where(blcc => blcc == Consts.ALL.ToString() || blcc == country).Any()