12

Rob Conery の Storefront シリーズで、Rob はLazyList<..>からデータを引き出すために構造を広範囲に使用しIQueryablesます。

  • System.Lazy<...>これは、現在 .NET 4.0 (およびおそらくそれ以前) で利用可能な構造とどのように異なるのでしょうか?

DoctaJones の優れた回答に基づく詳細:

  1. IQueryableとして操作したい場合、どちらかをお勧めしList<T>ますか?
    は現在フレームワークに含まれてLazy<T>いるため、将来のサポートと保守性にとってより安全な賭けであると思いますか?
  2. 匿名 ( ) 型の代わりに強力な型を使用したい場合var、次のステートメントは機能的に同等でしょうか?
    • Lazy<List<Products>> Products = new Lazy<List<Product>>();
    • LazyList<Product> = new LazyList<Product>();
4

1 に答える 1

17

LasyList <T>は、 IQueryable<T>ソースでのみ機能します。これはIList<T>の実装であり、指定されたIQueryable<T>からのすべての結果をプライベートリストに入力することによって機能します。初期化は、IList<T>メンバーのいずれかに初めてアクセスしたときに行われます。

使用例は次のようになります

var myList = new LazyList(products.Where(p => p.Name.StartsWith("T"));
//initialization occurs here
Console.Write(myList.Count);

System.Lazy <T>クラスは任意のタイプで機能し、IQueryable<T>に限定されません。レイジー初期化は、 Lazy<T>.Valueプロパティに初めてアクセスしたときに発生します。

使用例は次のようになります

var lazyString = new Lazy(() => "Hello world");
//initialization occurs here
Console.Write(lazyString.Value);

LazyList <T>の例を書き直して、Lazy<T>を次のように使用できます。

var myList = new Lazy(() => products.Where(p => p.Name.StartsWith("T").ToList());
//initialization occurs here
Console.Write(myList.Value.Count);

つまり、 LazyList<T>はIQueryable<T>でのみ機能し、Lazy<T>は任意のタイプで機能します。

LazyList <T>は、IQueryable<T>の結果をList<T>として使用したいが、それを使用するまで評価を行わせたくない場合の特定のユースケース用です。


拡張された質問に答えるための更新:

IQueryableをList<T>として操作したい場合は、どちらか一方をお勧めしますか?Lazy <T>は現在フレームワークに含まれているので、将来のサポートと保守性のためのより安全な賭けだと思いますか?

個人的にはどちらも使いません。IQueryableをお持ちの場合は、柔軟性を最大化するためにIQueryableとして保持します。IQueryableを維持することにより、(コンテキストがまだ生きている限り)LINQtoSQLのクエリ理解にアクセスできます。

たとえば、IQueryableで.ToList()を呼び出すと、LINQ to SQLに、ターゲットテーブルからすべての列を選択し、すべての結果をハイドレイトするように要求します(これは、特に数千の場合、非常にコストがかかる可能性があります)結果)。これは、「SELECT*FROMMyTable」のようなものに変換されます。

LINQ to SQLに結果の数を取得するように要求しているIQueryableで.Count()を呼び出すと、これは「SELECT COUNT(*)FROMMyTable」のように変換されます。これを行うことは、すべての結果をハイドレイトしてからカウントするよりもはるかに効率的です。特に、数値だけに関心がある場合はそうです。

IQueryable LINQ to SQLで.Where()を使用すると、SQLクエリのWHERE句に条件が追加されます。これは、使用する意図のない結果をハイドレイトするのではなく、関心のあるSQLからのみデータをプルすることを意味します。

ご覧のとおり、IQueryableを維持することで、物事をより柔軟にすることができます。ほとんどの場合、結果セット全体をハイドレイトするよりも優れたパフォーマンスが得られます。

匿名(var)型の代わりに強い型を使用したい場合、次のステートメントは機能的に同等ですか?

Lazy<List<Product>> products = new Lazy<List<Product>>(); 
LazyList<Product> products = new LazyList<Product>();

匿名タイピングと暗黙のタイピングを混同していると思います。varキーワードを使用して宣言された変数は、割り当てられている型と一致するように暗黙的に型指定されます。強く型付けされているため、最初の割り当て後に変更することはできません。

2つのステートメントは機能的に同等ではありません。LazyList<Product>はIList<Product>ですが、Lazy <List<Product>>はList<Product>を含むラッパーです。あなたは遅延評価リストの操作に特に興味があるので、LazyListはおそらくあなたの目的により具体的だと思います。

実際の製品リストが本当に必要かどうかを自問する必要があります。実際のリストを作成するやむを得ない理由がない場合は、IQueryableを使用します。

于 2010-04-22T11:27:17.103 に答える