0

以下のコメントは DEFERRED EXECUTION について正しいですか?

1. var x = dc.myTables.Select(r=>r);//yes
2. var x = dc.myTables.Where(..).Select(r=>new {..});//yes
3. var x = dc.myTables.Where(..).Select(r=>new MyCustomClass {..});//no

言い換えれば、カスタム クラス オブジェクトを投影すると常に熱心に実行されるといつも思っていました。しかし、それを支持/否定する参照を見つけることができませんでした(ただし、結果が矛盾しているため、投稿しています)

4

5 に答える 5

7

あなたの質問のすべてのステートメントは、遅延実行の例です。Selectandステートメントの内容はWhere、結果の値が遅延実行されるかどうかには影響しません。Select+Whereステートメント自体がそれを指示します 。

反例として、Sumメソッドを考えてみましょう。これは、入力が何であるかに関係なく、常に熱心に実行されます。

var sum = dc.myTables.Sum(...);  // Always eager 
于 2013-03-15T15:53:44.207 に答える
3

あなたの主張を証明するために、テストは次のようになります。

var tracer = string.Empty;
Func<inType, outType> map = r => {
       tracer = "set";
       return new outType(...);
    } 

var x = dc.myTables.Where(..).Select(map);

// this confirms x was never enumerated as tracer would be "set".
Assert.AreEqual(string.Empty, tracer);
// confirm that it would have enumerated if it could
CollectionAssert.IsNotEmpty(x);
于 2013-03-15T19:08:06.063 に答える
2

.Select(...) is always deferred.

When you're working with IQueryable<T>, this and other deferred execution methods build up an expression tree and this isn't ever compiled into an actual executable expression until it's iterated. That is, you need to:

  • Do a for-each on the projected enumerable.
  • Call a method that internally enumerates the enumerable (i.e. .Any(...), .Count(...), .ToList(...), ...).
于 2013-03-15T15:59:45.063 に答える
2

通常、シーケンスを返すメソッドは遅延実行を使用します。

IEnumerable<X> ---> Select ---> IEnumerable<Y>

単一のオブジェクトを返すメソッドは、次のことを行いません。

IEnumerable<X> ---> First ---> Y

したがって、 、 、 、 などのメソッドWhereSelect遅延Take実行Skipを使用できるGroupByため、OrderBy遅延実行を使用します。FirstSingleToListToArray

ここから

于 2013-03-15T15:56:54.463 に答える
2

すぐに実行を強制する唯一の方法は、コレクションの反復を強制することだと私は考えています。.ToArray()これを行うには、LINQを呼び出します。

于 2013-03-15T15:53:53.397 に答える