1. ホーム
  2. c#

[解決済み] IEnumerableの複数列挙の可能性に関する警告の処理

2022-03-25 17:24:09

質問

私のコードでは 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();
    // ...
 }

しかし、これはあくまで 不格好 .

このシナリオの場合、あなたならどうしますか?

解決方法は?

を取る際の問題点 IEnumerable をパラメータとして使用すると、呼び出し側に "私はこれを列挙したい" と伝えることになります。これは、呼び出し元に対して、何回列挙したいのかを伝えるものではありません。

<ブロッククオート

オブジェクトのパラメータをListに変更すれば、複数回の列挙を避けることができますが、その場合は 処理可能な最も高いオブジェクト .

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

ここでのセマンティックな欠落は、呼び出し側がメソッドの詳細を読む時間を取らずに、あなたが一度だけ反復処理すると仮定し、高価なオブジェクトを渡すかもしれないということです。あなたのメソッドのシグネチャは、そのどちらかを示していません。

メソッドのシグネチャを IList / ICollection そうすれば、少なくとも電話をかけてきた人は、あなたの期待することが明確になり、お金のかかるミスを避けることができます。

そうでなければ、このメソッドを見た開発者の多くは、一度だけ反復処理をしていると思うかもしれません。もし IEnumerable が重要なのであれば .ToList() をメソッドの冒頭に置く。

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