Il procedimento di conversione, di cui si è accennato nell'
articolo precedente, gode della massima flessibilità: ad esempio, i metodi del pattern possono essere implementati come metodi di istanza o di estensione – giacchè entrambi hanno la medesima sintassi di invocazione – ed i metodi possono richiedere delegati o
expression tree, dato che, come abbiamo visto, le
lambda expression possono essere convertite ad entrambi. Il vantaggio di tutto ciò? Immaginate di poter fare, sempre naturalmente da codice C#, tutto questo:
from o in orders
let t = o.Details.Sum(d => d.UnitPrice * d.Quantity)
where t >= 1000
select new {o.OrderID, Total = t};
from c in customers
from o in c.Orders
orderby o.Total descending
select new {c.Name, o.OrderID, o.Total};
from c in customers
join o in orders on c.CustomerID equals o.CustomerID
join d in details on o.OrderID equals d.OrderID
join p in products on d.ProductID equals p.ProductID
select new {c.Name, o.OrderDate, p.ProductName};
Infine, avendone parlato più volte, è bene spendere due parole sugli
expression tree che consentono, in sostanza, di rappresentare una
lambda expression come una struttura dati invece che come codice eseguibile. Per la precisione, una
lambda expression, che può essere convertita ad un tipo delegato D, è convertibile anche ad un
expression tree di tipo
. E' importante capire la differenza profonda fra le due conversioni: nel primo caso, viene generato del codice eseguibile, referenziato dal delegato; nel secondo, il codice, che rappresenta l'istanza di un
expression tree, viene creato tramite
. Il vantaggio è che un
expression tree è una rappresentazione
in-memory di una
lambda expression, efficiente, trasparente ed esplicita.
Un esempio dei due tipi di conversione è il seguente:
Func<int,int> f = x => x + 1 ||Codice
Expression<Func<int,int>> e = x => x + 1 ||Dati
ove, dato che esiste una conversione a
, ne esiste anche una a
Expression<Func<int,int>>
. Nel caso in esame, il delegato
referenzia un metodo che restituisce
x + 1, mentre l'
expression tree referenzia una struttura dati in memoria che descrive l'espressione
x + 1. Sia la struttura degli
expression tree, che gli operatori standard per le
query expression saranno descritti in specifiche separate. Da ultimo, vorrei ricordare che è disponibile per il download un
video che mostra le principali novità di C# 3.0
in azione.