1153 Stimmen

Warum sollten Sie Expression<Func<T>> und nicht Func<T> verwenden?

Ich verstehe Lambdas und die Func et Action Delegierte. Aber Ausdrücke verblüffen mich.

Unter welchen Umständen würden Sie eine Expression<Func<T>> als eine einfache alte Func<T> ?

44voto

Marc Gravell Punkte 970173

LINQ ist das kanonische Beispiel (z.B. für die Kommunikation mit einer Datenbank), aber in Wahrheit kann man jedes Mal, wenn man sich mehr für den Ausdruck von was zu tun, als es tatsächlich zu tun. Ich verwende diesen Ansatz zum Beispiel im RPC-Stack von protobuf-net (um Code-Generierung usw. zu vermeiden) - Sie rufen also eine Methode mit:

string result = client.Invoke(svc => svc.SomeMethod(arg1, arg2, ...));

Dadurch wird der Ausdrucksbaum dekonstruiert, um Folgendes aufzulösen SomeMethod (und den Wert der einzelnen Argumente), führt den RPC-Aufruf durch, aktualisiert alle ref / out args, und gibt das Ergebnis des Fernaufrufs zurück. Dies ist nur über den Ausdrucksbaum möglich. Ich behandle dies genauer aquí .

Ein weiteres Beispiel ist die manuelle Erstellung der Ausdrucksbäume zum Zweck der Kompilierung zu einem Lambda, wie sie von der generische Operatoren Code.

29voto

mhenry1384 Punkte 7322

Bei der Verwendung von LINQ-to-SQL ist die Übergabe von Func<> s in Where() ou Count() ist schlecht. Wirklich schlecht. Wenn Sie eine Func<> dann ruft es die IEnumerable LINQ-Zeug anstelle von IQueryable was bedeutet, dass ganze Tabellen herangezogen werden und dann gefiltert. Expression<Func<>> ist wesentlich schneller, weil es die Filterung durchführt auf dem SQL-Server - Dies gilt insbesondere, wenn Sie eine Datenbank abfragen, die auf einem anderen Server liegt.

26voto

Andrew Hare Punkte 332190

Sie würden einen Ausdruck verwenden, wenn Sie Ihre Funktion als Daten und nicht als Code behandeln wollen. Sie können dies tun, wenn Sie den Code (als Daten) manipulieren wollen. Wenn Sie keine Notwendigkeit für Ausdrücke sehen, brauchen Sie sie meistens nicht zu verwenden.

26voto

Luaan Punkte 59767

Der Hauptgrund dafür ist, dass Sie den Code nicht direkt ausführen, sondern nur überprüfen wollen. Dafür kann es eine Vielzahl von Gründen geben:

  • Zuordnung des Codes zu einer anderen Umgebung (z. B. C#-Code zu SQL in Entity Framework)
  • Ersetzen von Teilen des Codes während der Laufzeit (dynamische Programmierung oder sogar einfache DRY-Techniken)
  • Code-Validierung (sehr nützlich bei der Emulation von Skripten oder bei der Analyse)
  • Serialisierung - Ausdrücke können relativ einfach und sicher serialisiert werden, Delegierte nicht
  • Sicherheit durch starke Typisierung bei Dingen, die nicht von Natur aus stark typisiert sind, und Ausnutzung von Compiler-Prüfungen, auch wenn Sie dynamische Aufrufe zur Laufzeit durchführen (ASP.NET MVC 5 mit Razor ist ein gutes Beispiel)

15voto

Default Punkte 524

Stark vereinfacht, aber Func ist eine Maschine, während Expression eine Blaupause ist :D

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X