IEnumerable の複数の列挙の可能性に関する警告の処理 質問する

IEnumerable の複数の列挙の可能性に関する警告の処理 質問する

私のコードでは、 を複数回使用する必要がありIEnumerable<>、その結果、「 の複数の列挙の可能性があります」という ReSharper エラーが発生しますIEnumerable

サンプルコード:

public List<object> Foo(IEnumerable<object> objects)
{
    if (objects == null || !objects.Any())
        throw new ArgumentException();
        
    var firstObject = objects.First();
    var list = DoSomeThing(firstObject);        
    var secondList = DoSomeThingElse(objects);
    list.AddRange(secondList);
    
    return list;
}
  • objectsパラメータを に変更して、複数の列挙の可能性を回避することはできますListが、その場合、処理できる最高のオブジェクトを取得できません。
  • 他にできることは、メソッドの先頭で を にIEnumerable変換することです。List

 public List<object> Foo(IEnumerable<object> objects)
 {
    var objectList = objects.ToList();
    // ...
 }

しかし、これはただ気まずいだけです。

このシナリオではあなたはどうしますか?

ベストアンサー1

をパラメータとして取る場合の問題IEnumerableは、呼び出し元に「これを列挙したい」と伝えることです。列挙する回数は伝えません。

オブジェクト パラメータを List に変更して、複数の列挙を回避することはできますが、その場合、処理できる最高のオブジェクトを取得できません。

最も高いオブジェクトを取得するという目標は崇高ですが、想定の余地が多すぎます。このメソッドに LINQ to SQL クエリを渡して、それを 2 回列挙する (毎回異なる結果になる可能性がある) ことを本当に望みますか?

ここで意味が欠けているのは、メソッドの詳細を読む時間がないかもしれない呼び出し元が、反復処理は 1 回だけであると想定し、高価なオブジェクトを渡す可能性があることです。メソッド シグネチャではどちらの場合も示されていません。

メソッド シグネチャをIList/に変更することでICollection、少なくとも呼び出し元に対して期待していることが明確になり、コストのかかる間違いを回避できます。

そうしないと、メソッドを見るほとんどの開発者は、反復処理が 1 回だけであると想定するかもしれません。 を取ることが非常に重要な場合は、メソッドの先頭でIEnumerableを行うことを検討する必要があります。.ToList()

.NET に、Add/Remove などのメソッドのない IEnumerable + Count + Indexer のインターフェイスがないのは残念です。これがこの問題を解決するのではないかと思います。

おすすめ記事