3

私は次の製品リストを持っています

List<Product> products = new List<Product> {
                new Product { 
                    ProductID = 1, 
                    ProductName = "first candy", 
                    UnitPrice = (decimal)10.0 },
                new Product { 
                    ProductID = 2, 
                    ProductName = "second candy", 
                    UnitPrice = (decimal)35.0 },
                new Product { 
                    ProductID = 3, 
                    ProductName = "first vegetable", 
                    UnitPrice = (decimal)6.0 },
                new Product { 
                    ProductID = 4, 
                    ProductName = "second vegetable", 
                    UnitPrice = (decimal)15.0 },
                new Product { 
                    ProductID = 5, 
                    ProductName = "third product", 
                    UnitPrice = (decimal)55.0 }
            };

var veges1 = products.Get(IsVege);   //Get is a Extension method and IsVege is a Predicate

//Predicate
 public static bool IsVege(Product p)
        {
            return p.ProductName.Contains("vegetable");
        }

//Extension Method
public static IEnumerable<T> Get<T>(this IEnumerable<T> source, Func<T, bool> predicate)
        {
            foreach (T item in source)
            {
                if (predicate(item))
                    yield return item;
            }
        }

これらのトピックについては非常に遅れていることはわかっていますが、Visual Studio でデバッグして理解しようとしています。

すべての関数(述語、拡張メソッド)にブレークポイントがあります

私の質問は

1.以下の行が実行されるとどうなりますか

var veges1 = products.Get(IsVege);   // i dont see the breakpoint hitting either predicate or GET method)

しかし、デバッグ中の結果ビューには、veges1 の出力が表示されます。

以下のコードを打った場合

veges1.Count()   // Breakpoint in Predicate and GET is hit and i got the count value.

これはどのように作動しますか ?ご理解いただけますでしょうか。

PS:これには多くの例と質問があることを知っています。この例で理解しようとしているのは、物事を理解しやすくするためです。

更新された質問

上記と同じサンプルで、ラムダ式で同じことをしようとしています

var veges4 = products.Get(p => p.ProductName.Contains("vegetable"));

期待どおりの結果が得られます。

GET は私の拡張メソッドですが、その行が実行されると、GET メソッドのブレークポイントが呼び出されませんでしたか?

ありがとう

4

3 に答える 3

1

LINQ と反復子は遅延実行を使用します。簡単に言えば、yield値が必要になるまで待ってから実行続けます。

veges1結果ではなくクエリが含まれます。クエリの実行が必要な操作をクエリに対して実行した場合にのみ、作業が行われます。たとえば、 of を与えるにはCountveges1完全Getに実行する必要があります。別の例として、 を実行した場合veges1.First、ループの最初の反復のみを実行Getする必要があります。

クエリの実行を強制する一般的な方法は、次を使用することToListです。

// veges1 will now contain a List<Product> instead of an IEnumerable<Product>
var veges1 = products.Get(IsVege).ToList();
于 2013-04-03T07:42:41.513 に答える