SORU
15 EYLÜL 2010, ÇARŞAMBA


Farklı şekilde İfade ediyor.() Alıntı bu İfade.() Sürekli zaten yapamaz mı?

Not: önceki soru farkındayım “What is the purpose of LINQ's Expression.Quote method?eğer soruma cevap olmadığını göreceksiniz okumaya devam ederseniz , ama.

Expression.Quote() belirtilen amacı ne demek olduğunu anladım. Ancak, Expression.Constant() aynı amaç (Expression.Constant() zaten kullanılan tüm amaçlar için ek olarak) için de kullanılabilir. Bu nedenle, Expression.Quote() hiç gerekli olduğunu anlamıyorum.

Göstermek için bunu yazdım hızlı bir örnek, burada ki alışıldığı kullanın Quote (bkz: çizgi ile işaretli ünlem işareti) ama eskisi Constant yerine ve işe yaradı aynı zamanda:

string[] array = { "one", "two", "three" };

// This example constructs an expression tree equivalent to the lambda:
// str => str.AsQueryable().Any(ch => ch == 'e')

Expression<Func<char, bool>> innerLambda = ch => ch == 'e';

var str = Expression.Parameter(typeof(string), "str");
var expr =
    Expression.Lambda<Func<string, bool>>(
        Expression.Call(typeof(Queryable), "Any", new Type[] { typeof(char) },
            Expression.Call(typeof(Queryable), "AsQueryable",
                            new Type[] { typeof(char) }, str),
            // !!!
            Expression.Constant(innerLambda)    // <--- !!!
        ),
        str
    );

// Works like a charm (prints one and three)
foreach (var str in array.AsQueryable().Where(expr))
    Console.WriteLine(str);

expr.ToString() çıkış her ikisi için de aynı, çok Constant Quote kullanmak ister.

Yukarıdaki gözlemler Expression.Quote() gereksiz görünüyor. C# derleyicisi olabilir yapılan derleme iç içe lambda ifadeleri bir ifade ağaç içeren Expression.Constant() yerine Expression.Quote() ve herhangi bir SERİ sorgu sağlayıcısı isteyen süreci ifade ağaçlara başka bir sorgu dili (SQL) diye dışarı bakmak için ConstantExpression tip Expression<TDelegate> yerine UnaryExpression özel Quote düğüm türü, ve her şey aynı olurdu.

Neyi kaçırıyorum? Neden Expression.Quote() UnaryExpression Quote özel düğüm türü icat etti?

CEVAP
20 EYLÜL 2010, PAZARTESİ


Kısa cevap:

Alıntı operatöroperatörhangikapatma işlemi sonucunda dilini neden olmaktadır. Sabitler sadece değerlerdir.

Tırnak ve sabitler farklıanlamlarıve bu nedenle varifade bir ağaçta farklı gösterimi. Çok farklı iki şey için aynı temsile sahipson derecekarmaşık ve hata eğilimli.

Uzun cevap:

Aşağıdakileri göz önünde bulundurun:

(int s)=>(int t)=>s t

Dış dış lambda lambda parametre bağlı toplayıcılar için bir fabrika.

Şimdi, daha sonra derlenmiş ve idam edilecek bir ifade ağaç olarak temsil etmesi dileğiyle diyelim. İfade ağaç gövdesi ne olmalıdır?Derlenmiş devletin bir temsilci ya da bir ifade ağacı dönmek isteyip istemediğinizi bağlıdır.

Başlayalım ilginç davanın düşmesine izin. Eğer bir temsilci dönmek istiyorsanız, o zaman Tırnak veya Sabit olmadığı sorusu da tartışmalı bir nokta

        var ps = Expression.Parameter(typeof(int), "s");
        var pt = Expression.Parameter(typeof(int), "t");
        var ex1 = Expression.Lambda(
                Expression.Lambda(
                    Expression.Add(ps, pt),
                pt),
            ps);

        var f1a = (Func<int, Func<int, int>>) ex1.Compile();
        var f1b = f1a(100);
        Console.WriteLine(f1b(123));

Bu iç içe lambda lambda; derleyici bir işlevi, bir devlet üzerinde kapalı dış lambda için oluşturulan bir temsilci olarak İçişleri lambda oluşturur. Bu durumda artık hesaba katmamız lazım.

Derlenmiş bir devlet dönmek isteyecek sanırımifade ağaçiç. Bunu yapmanın iki yolu vardır: kolay yol ve zor yol.

Zor yoldan yerine

(int s)=>(int t)=>s t

biz gerçekten ne demek olduğunu

(int s)=>Expression.Lambda(Expression.Add(...

Ve daha sonra ifade ağacı oluşturmakbuüretimbu pisliği:

        Expression.Lambda(
            Expression.Call(typeof(Expression).GetMethod("Lambda", ...

blah blah blah, yansıma kod satırları lambda yapmak için onlarca.Amaç alıntı operatörü söyle ifade ağaç derleyici bizim istediğimiz verilen lambda tedavi olmak gibi bir ifade ağacı, bir işlevi kalmadan açıkça ifade ağacı oluşturmak nesil kod.

Kolay yolu:

        var ex2 = Expression.Lambda(
            Expression.Quote(
                Expression.Lambda(
                    Expression.Add(ps, pt),
                pt)),
            ps);

        var f2a = (Func<int, Expression<Func<int, int>>>)ex2.Compile();
        var f2b = f2a(200).Compile();
        Console.WriteLine(f2b(123));

Ve gerçekten de, eğer derleme ve bu kod çalıştırmak doğru cevabı alırsın.

Alıntı operatörü bir dış değişken, dış lambda resmi bir parametre kullanan İçişleri lambda kapatma semantik neden olan operatör olduğuna dikkat edin.

Soru: neden Alıntı ortadan kaldırmak ve bu aynı şeyi yapmak değil mi?

        var ex3 = Expression.Lambda(
            Expression.Constant(
                Expression.Lambda(
                    Expression.Add(ps, pt),
                pt)),
            ps);

        var f3a = (Func<int, Expression<Func<int, int>>>)ex3.Compile();
        var f3b = f3a(300).Compile();
        Console.WriteLine(f3b(123));

Sürekli kapatma semantiği yol açmaz. Neden mi? Bu bir olduğunu söyledisürekli. Sadece bir değer. Derleyici teslim olarak mükemmel olmalıdır; derleyici o değeri bir dökümü oluşturmak mümkün gereken bir yığın olmalıdır.

Göreceksin bu olay kapanmaz eğer bunu yaparsanız kaynaklı bir durumdur. "'s' türü 'System.değişken beri Int32'" çağırma özel. tanımlı değil

Sadece alıntı ifade ağaçlardan temsilci oluşturulması için kod jeneratör inceledim ve 2006 yılında kodun içine geri koydum bir yorum hala var ne yazık ki. (bir kenara: BİLGİNİZE, göndere dış parametredirsnapshottedalıntı ifade ağaç çalışma zamanı derleyicisi tarafından temsilci olarak şeyleşiyor zaman sürekli içine. Kodunu şu an hatırlamıyorum bu şekilde yazdım neden iyi bir nedeni vardı, ama kapatma tanıtılması üzerinde kötü yan etkisi vardeğerlerdış parametreleri yerine kapatılmasıdeğişkenler. Anlaşılan takım olan kalıtsal bir kod karar için düzeltme bu kusur, eğer öyleyse size güvenerek mutasyon kapalı-dış parametre gözlenen bir derlenmiş alıntı iç lambda, olacaksın hayal kırıklığına uğrattı. Ancak, bu oldukça kötü bir programlama uygulama için hem (1) mutasyona resmi bir parametre (2) dayanmak mutasyon bir dış değişken yapardım etmenizi tavsiye değişim programı kullanın bu iki kötü programlama uygulamaları yerine beklemek için bir düzeltme hangi görünmez olmak için gelecek. Hata için özür dilerim.)

Yani, soruyu tekrarlamak için:

C# derleyici bir ifade ağacı İfade içeren iç içe geçmiş lambda ifadeleri derlemek için yapılmış olabilir.() Sürekli İfade yerine.Alıntı(), ve herhangi bir SERİ sorgu sağlayıcısı isteyen süreci ifade ağaçlara başka bir sorgu dili (SQL) diye dışarı bakmak için bir ConstantExpression tip İfade yerine bir UnaryExpression ile özel Alıntı düğüm türü, ve her şey aynı olurdu.

Haklısınız. Bizolabilirkodlama anlamsal bilgi anlamına gelir "bu değer üzerinde kapanış semantik ikna etmek"bir bayrak gibi sabit ifade türünü kullanarak.

"Sabit" o zaman bir anlamı olurdu "bu sabit değersürecebu tür bir ifade ağaç türü oluyorvedeğer geçerli bir ifade ağacı, bu durumda, bunun yerine kullanım değeri olduğunu ifade ağaç dan kaynaklanan yeniden İçişleri verilen ifade ağaç için neden kapatma semantiği bağlamında herhangi bir dış Lambda biz olabilir şu an.

Ama nedenbu çılgınca bir şey yapabilir miyiz?Alıntı operatörü delicesine karmaşık bir operatörkullanılmalıdıraçıkçabunu kullanmak için gidiyoruz. Öneriyorsan o olmak için cimri değil ekleme ekstra bir fabrika yöntemi ve düğüm türü arasında birkaç düzine zaten var ya, biz eklemek bir garip köşe durumda sabitler, böylece sabit, bazen mantıksal sabitler, ve bazen onlar yeniden Lambda ile kapatılması anlambilim.

Ayrıca sürekli anlamına gelmez bu biraz garip bir etkisi olurdu "bu değer". Bazı tuhaf nedenle senin için sanırımistedimüçüncü vaka değil-yeniden başvuru dışsal bir değişken olan en küçük bir ifade ağaç dağıtan bir temsilci ifadeye bir ağaç derlemek için yukarıda? Neden? Belki de ondanderleyici test ediyoruzve sürekli başka analiz daha sonra gerçekleştirebileceğiniz ile geçmek istiyorum. Teklifinizi bu imkansız olurdu; ifade ağaç türü olan herhangi bir sabit bağımsız olarak yazılmış. Makul bir beklenti var "" "bu değer". kullanmak anlamına gelir sürekli "Sabit" bir "ben" düğüm. diyorsunuz. Sürekli işlemcinin işi ne tahmin etmek değildemekiçin Türüne göre söylüyorlar.

Ve notun dersin sen şimdi koyarak yükü anlama (anlayış sürekli karmaşık semantik yani "sabit" bir durumda ve "neden kapatılması anlamını" dayalı bir bayraktür sistemiüzerineherifade ağaç semantik analiz yapan sağlayıcısı, yalnızca Microsoft sağlayıcıları üzerine.Kaç üçüncü taraf sağlayıcıları yanlış olsun ki?

"Alıntı" olduğunu sallayarak büyük bir kırmızı bayrak diyor ki, "hey dostum, buraya bak, ben bir iç içe lambda ifadesi ve ben tuhaf semantik eğer ben kapalı bir dış değişken!" oysa "Sabit" olduğunu söyleyerek, "ben hiçbir şey daha fazla bir değer; beni gördüğünüz gibi fit." Bir şey karmaşık ve tehlikeli olduğunu ne zaman kırmızı bayrak sallayan, kullanıcı ile kazı yaparak bu gerçeği saklamıyorum yapmak istiyoruztür sistemibu değer, bir özel biri olup olmadığını öğrenmek için ya da değil.

Ayrıca, aşırılıktan kaçınarak bir gol bile fikri yanlıştır. Tabii, gereksiz, kafa karıştırıcı, aşırılıktan kaçınarak bir hedeftir, ama en fazlalığı iyi bir şey; fazlalık açıklık oluşturur. Yeni fabrika yöntemleri ve düğüm türü vardırucuz. Her biri temiz bir işlemi temsil eder, böylece ihtiyacımız olduğu kadar çok yapabiliriz. "Bu alana sürece bir şey, bu durumda başka bir şey demek bu şey için ayarlanır." demek gibi pis oyunlara başvurmaya ihtiyacımız yok

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • gadgetgal38

    gadgetgal38

    9 HAZİRAN 2009
  • Jeb Corliss

    Jeb Corliss

    17 Kasım 2006
  • UKF

    UKF

    2 Aralık 2009