2010-11-23 6 views
7

間のいずれかの機能的な違いがあります:は、これら2つのlinq式は機能的に同等ですか?

if (photos.Any(it => it.Archived)) 

if (photos.Where(it => it.Archived).Any()) 

そうならば、他の上で1つを使用するために、より説得力のある理由があるの?

+0

結果は同じですが、パフォーマンスの違いがあるかどうかは100%確信しているわけではありません。 –

+0

Visual Studioでは、ILを自分で調べることができます。 funktionのブレークポイントを教えてください –

答えて

8

機能的に、彼らは同じことを行います。パフォーマンスは、特定のプロバイダに依存するが、例えばLINQで両方のフォームが正確に同じSQL生成SQLに:私はそれがわずかにより明確に思えるように私は、最初のオプションを使用したいものを選択する必要がある場合は

SELECT 
    (CASE 
     WHEN EXISTS(
      SELECT NULL AS [EMPTY] 
      FROM [dbo].[photos] AS [t0] 
      WHERE [t0].[Archived] = 1 
      ) THEN 1 
     ELSE 0 
    END) AS [value] 

を私。

+1

実際の実装がプロバイダーに任されているというヒントのために+1。 –

+0

@Tim Jarvis:ありがとう。私はプロバイダ固有のことをもう少し明示するために、ちょうど "ヒント"から言い換えました。 –

2

いいえ、違いはありません実用的な違いメソッドの現在の.NET Frameworkの実装です。遅延実行のため、一致が検出されて停止するまで、両方ともphotosを列挙します。 (これがLinqからオブジェクトへのものであれば、他のプロバイダは異なる動作をする可能性があります)。

ニッピキーを取得したい場合は、小さな実装上の違いがあります。 (あなたは、フレームワークのソースでそれを見ることができます):

Anyは、単にあなたが渡すコレクションの種類に応じて、Where戻りWhereArrayIteratorWhereListIterator、またはWhereEnumerableIteratorいずれかとしている、foreachのを使用してコレクションを反復処理I避難所」。これについては深く掘り下げましたが、配列やリストを使用する場合にチェーン拡張メソッドを最適化できるようにするためにこれが行われていると思います。 Anyはシンプルforeachが含まれている言い換えれば

は、Whereは、この処理を行います。

if (source is TSource[]) return new WhereArrayIterator<TSource>((TSource[])source, predicate); 
    if (source is List<TSource>) return new WhereListIterator<TSource>((List<TSource>)source, predicate); 
    return new WhereEnumerableIterator<TSource>(source, predicate); 
+0

2番目のバージョンのようにnull述語が指定されている場合、ArgumentNullExceptionがスローされたと思っていましたが、LINQをあまり使用しません。 – stonemetal

+0

どちらもnullをスローします。 – driis

+0

内部について概説してくれてありがとう。 – CedricB

2

式として、同じ結果が得られます。しかし、この結果を生み出すメカニズムはわずかに異なります。ただし、両方とも元のシーケンスと同じ数の項目を処理します。

私はそれがより短く、2番目のものよりもそれを選択する際の明瞭さ、読みやすさ、保守性の損失はありません。

関連する問題