17

このコードを実行した後:

var input = new List<T>( ... );
var result = input.Select( t => new U(t) );

U first1 = null;
foreach ( U u1 in result )
    if ( first1 == null )
        first1 = u1;

U first2 = null;
foreach ( U u2 in result )
    if ( first2 == null )
        first2 = u2;

次に、両方のUが同じTをラップしていても、'first1 == first2'はfalseと評価されます。まだテストしていませんが、.ToList()または.ToArray()をチェーンすることでtrueと評価できると思います。 Select()呼び出しに。

この単純な図よりもはるかに複雑な実際のコードでは、.ToList()または.ToArray()のどちらを追加するかを決定するために使用する経験則は何ですか?私の最初の考えは、複数回繰り返される可能性のある参照式か、潜在的な反復が明らかでない場合に安全にするために、結果が決して変わらない参照式のいずれかです。

4

2 に答える 2

20

残念ながら、ここには良い「ハードで速い」ルールはないと思います。これは、結果がどのように使用されるか、およびクエリ自体が実際に何を行っているかに大きく依存します。

私の最初の考えは、複数回繰り返される可能性のある式か、潜在的な反復が明らかでない場合に安全にするために、結果が決して変わらない式のいずれかです。

一般に、クエリの結果を複数回使用する場合は、ToList()またはを介して保存することをお勧めしToArray()ます。これは、LINQクエリが「高価な」クエリである場合に特に当てはまります。これは、高価な操作が複数回実行されるのを防ぐためです。

通常、結果を列挙するだけの場合は、そのままにしておきますIEnumerable<T>。結果を保存する場合、または結果を複数回使用する場合は、コレクションに保存すると便利です。

注目すべきもう1つの場所は、結果をパブリックAPIで返すかどうかです。多くの場合、戻るのは良いことですがIEnumerable<T>、予想されるユースケースによってはToList()、操作が複数回実行されないようにするために使用することを検討することをお勧めします。

使用するかどうかToList()ToArray()、結果をどのように使用するかによって異なります。それぞれに関連するコストはほぼ同じです(ToList()入力がない場合、実際には実行オーバーヘッドがわずかに低くなりますICollection<T>)。通常、アレイに対する特定のニーズや要望がない限り、私は優先ToList()します。ToArray()

于 2012-08-18T01:10:42.890 に答える
3

ToListコンストラクターを呼び出しList<T>(IEnumerable<T>)てを作成し、内部クラスを使用しList<T>て配列を拡張します。 ToArraryBuffer<T>

ソースコレクション(IEnumerable<T>)がインターフェイスを実装している場合ICollection、2つのメソッドは同様のコードロジックを使用してデータをコピーします。

ICollection.CopyTo(array, 0);  

それ以外の場合は、動的ToListに作成します。List<T>要素をToArray1つずつ新しい配列にコピーします。配列がいっぱいの場合、メソッドはデータを保持するために配列サイズを2倍にします。最後に、メソッドはソースコレクションのサイズに基づいて別の配列を返します。

于 2012-08-18T01:12:29.143 に答える