6

私は次のコードを書きました:

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

これは何を意味するのでしょうか?なぜこれが警告なのですか?

4

3 に答える 3

9

LINQクエリは、結果を処理するまで実行を延期します。この場合、Contains()同じコレクションを2回呼び出すと、結果が2回列挙される可能性があり、クエリによっては、パフォーマンスの問題が発生する可能性があります。

これを解決するToList()には、クエリの最後に呼び出しを追加するだけで、クエリの実行が強制され、結果が1回だけ保存されます。

于 2012-12-20T15:38:56.693 に答える
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();
于 2012-12-20T15:39:05.907 に答える
1

IEnumerableこれは、 2回(またはそれ以上)の内容を計算する可能性があることを意味します。これがデータベースの呼び出しのように高価な場合、これはパフォーマンスに悪影響を及ぼします。基になるソースがでList<T>あり、単純な予測または他の安価なものがある場合、これは問題ではありません。

もちろん、列挙型を1回だけ使用するように式を書き直すこともできます。

!blackListCountriesCodes.Contains(Consts.ALL.ToString())
    && !blackListCountriesCodes.Contains(country)

次のように書き直すことができます

!blackListCountriesCodes
    .Where(blcc => blcc == Consts.ALL.ToString() || blcc == country).Any()
于 2012-12-20T15:39:59.140 に答える