2009-10-07 14 views
16

Dieser wurde von meinem Sprach-Guru-Mitarbeiter inspiriert, der keinen guten Nutzen für sie zu finden scheint, und nach ein paar lahmen eigenen Versuchen würde ich dem zustimmen müssen.Was ist ein guter Anwendungsfall für .NET 4.0 Expression Trees?

Jetzt weiß ich, dass diese Konzepte dazu neigen, viel leichter zu fließen, sobald Sie ein paar gute praktische Gründe haben.

Im Moment scheint es, als ob der einzige Zweck darin besteht, Ihnen zu erlauben, einen Linq-Provider zu schreiben?

Ist es das ?? Gibt es noch andere Vorteile?

+3

http://stackoverflow.com/questions/403088/practical-use-of-expression-trees –

Antwort

15

Ausdrucksbaum sind so stark, weil sie Sie Code wie Daten behandeln lassen. Benutzer sind daran gewöhnt, Daten zu sammeln, zu speichern und später darauf zurückzukommen.

Ausdrucksbäume lassen Sie dasselbe mit Code machen. Beispielsweise können Sie die Eingaben Ihres Benutzers (Kontrollkästchen, Nummernkreise usw.) übernehmen und in einen Ausdrucksbaum übersetzen. Dieser Ausdrucksbaum kann dann ausgeführt oder für die spätere Verwendung gespeichert werden. Sehr cool.

Denken Sie an die praktischen Anwendungen rund um das Erstellen von Berichten wie das Erstellen und Speichern von Datenfiltern und Datenzuordnungen. Eine weitere praktische Anwendung wäre die Unterstützung von benutzerdefinierten Arbeitsabläufen in Ihrer Anwendung basierend auf benutzerdefinierten Regeln.

Hier ist ein bisschen MSDN-Code auf Serialisierung von Ausdrucksbäumen (http://code.msdn.microsoft.com/exprserialization), die die Ideen fließen sollten.

+0

Cool! Dies ist eine Antwort, die zu meiner speziellen Denkweise passt. Schöne Beispiele! Ich sehe jetzt, wie dies in anderen Teilen des Frameworks verwendet wird. Also wird das viel in WPF verwendet? – KevinDeus

+0

Danke. Freut mich, dass geholfen hat. Ich habe (wahrscheinlich zu viel) über WPF nachgedacht und wie verrückt nützliche funktionale Programmierkonzepte wie Lambdas und Expressionsbäume im Kern gewesen wären. Problem ist, dass WPF mit .NET 3.0 veröffentlicht wurde und LINQ in .NET 3.5 veröffentlicht wurde. In Zukunft würde ich hoffen, dass die WPF/Silverlight-Teams umrüsten werden. XAML wäre OK außer für alle verflixten Strings :). Starten Sie Relector und sehen Sie, was sie für Dinge wie System.Windows.DataTrigger tun müssen. Ihre Klage könnte ein Katalysator für LINQ gewesen sein. –

3

.NET 4.0 Expression Bäume sind auch die Grundlage für das DLR AST

8

Sie Expression Trees können Sie eine Domänensprache in ausführbaren Code zu transformieren.

1

Ich hatte eine gute Erfahrung damit, meine domänenspezifischen Sprach-ASTs in Ausdrucksbäume umzuwandeln. Es ist auch ziemlich einfach mit einem ANTLR Tree-Adapter, einen Expression-Baum direkt aus der Grammatik zu erstellen.

4

Eine Lösung auf der Suche nach einem Problem, eh?

Ausdrucksbäume ermöglichen es Ihnen, Code als eine transformierbare Datenstruktur darzustellen, daher sind sie perfekt zum Umwandeln zwischen Sprachen geeignet. Linq To SQL ist derzeit der mächtigste.

Eine andere Verwendung außer DSLs (die Transformation ist) ist die Parallelisierung (die Aufspaltung) und Beispiel in diesem Raum ist PLINQ.

+0

ja eine Lösung suchen für ein Problem wie Twitter :) – Surya

1

Sie können Ausdrucksbaum als Code-Generator mit einer höheren Abstraktionsebene dann Assembly emit und schneller als CodeCompiler verwenden. Hier ist ein Beweis für das Konzept, das ich verwendet habe, um unser Team davon zu überzeugen, sie als Ersatz für CodeCompiler zu verwenden.

[TestClass] 
public class WhenINeedToAccessPropertiesByNameHavingATypeReference 
{ 
    public class SomeCategoryData 
    { 
     public DateTime CreatedDate { get; set; } 
    } 

    [TestMethod] 
    public void ICanDoThatWithAnExpressionAndItPerformsWell() 
    { 
     // INIT 

     var someCategoryData = 
      Enumerable.Range(1970, 100).Select(year => 
       new SomeCategoryData { CreatedDate = new DateTime(year, 1, 1) }).Cast<object>(); 
     var t = typeof(SomeCategoryData); // or it can be: t = someCategoryData.First().GetType(); 
     var compiled = Stopwatch.StartNew(); 

     // ACT 

     var filter = AccessPropertyByNameInCompiledMannerSomehow(t, "CreatedDate"); 

     // ASSERT 

     Trace.WriteLine(string.Format("compiled in: {0}", compiled.Elapsed)); 
     Assert.IsTrue(compiled.ElapsedMilliseconds < 3, "compiles fast enough"); 

     var executed = Stopwatch.StartNew(); 

     // ACT 
     List<object> result = null; 
     for (var i = 0; i < 10000; i++) 
     { 
      result = someCategoryData.Where(d => filter(d, new DateTime(2000, 1, 1), new DateTime(2009, 1, 1))) 
       .ToList(); 
     } 
     executed.Stop(); 
     Trace.WriteLine(string.Format("executed in: {0}", executed.Elapsed)); 

     // ASSERT 
     Assert.AreEqual(10, result.Count, "insure compiled code actually works"); 
     Assert.IsTrue(executed.ElapsedMilliseconds < 300, "runs fast enough"); 
    } 

    private static Func<object, DateTime, DateTime, bool> 
     AccessPropertyByNameInCompiledMannerSomehow(Type t, string fieldToFilterBy) 
    { 
     var objectParameter = Expression.Parameter(typeof(object), "p"); 
     var instance = Expression.Convert(objectParameter, t); 
     var lower = Expression.Parameter(typeof(DateTime), "l"); 
     var upper = Expression.Parameter(typeof(DateTime), "u"); 

     var composite = Expression.Lambda<Func<object, DateTime, DateTime, bool>>(
      Expression.And(
       Expression.LessThanOrEqual(
        lower, 
        Expression.PropertyOrField(instance, fieldToFilterBy) 
        ), 
       Expression.GreaterThanOrEqual(
        upper, 
        Expression.PropertyOrField(instance, fieldToFilterBy) 
        ) 
       ), objectParameter, lower, upper 
      ); 

     return composite.Compile(); 
    } 
} 
2

Die schnelle Antwort ist "nein, es ist nicht nur für LINQ-Anbieter jetzt". Zunächst wurden Ausdrucksbäume um die dynamische Sprachlaufzeit erweitert, um dynamische Sprachen zu unterstützen. Wenn Sie Ihre eigene dynamische Sprache in .NET portieren möchten (wie IronPython und IronRuby), müssen Sie im Grunde Ausdrucksbäume verwenden. OK, nicht so viele Leute haben ihre eigenen Sprachen. Was sind andere Anwendungsfälle? Eine davon besteht darin, zur Laufzeit dynamischen Code zu generieren.Ich habe hier ein Beispiel: Generating Dynamic Methods with Expression Trees in Visual Studio 2010. Es wird erläutert, wie Sie ETs anstelle von MSIL verwenden können, um dynamische Methoden zu erstellen. Tatsächlich gibt es sogar in .NET 3.5 einige Anwendungsfälle für Ausdrucksbäume außerhalb von LINQ, aber diese Beiträge müssen noch geschrieben werden.

1

Ich habe einige Beispiele here

(traurig über die gebrochene Code-Formatierung)

Verwandte Themen