Appunti
Espressioni lambda
Questo nuovo potente meccanismo di programmazione permette di utilizzare in modo semplice funzioni dalla struttura lineare e veloce, che altrimenti
dovrebbero essere implementate con i Delegate. Ogni espressione lambda non è altro che un oggetto di tipo Func, del namespace System. Questi
oggetti rappresentano una funzione (sì, proprio una Function come la si intende comunemente), che, come tale, esegue una certa operazione su uno
o più parametri dati e restituisce un valore. La sintassi generale usata per assegnare un valore a un'espressione lambda è
Ecco un semplice esempio:'Assumiamo per ora una conversione implicita Dim L =([Parametri]) [Operazioni] Function
In particolare, l'espressione usata come esempio si potrebbe tradurre con una normale funzione:Module Module1Sub Main() 'Questa semplice espressione lambda moltiplica per due 'un numero dato. La dichiarazione di funzione avviene 'in modo normale, anche se si può omettere ByVal. 'Di seguito a questa, però, è possibile 'specificare una e una sola espressione, che 'costituirà il valore di ritorno della funzione Dim DoubleIt =Function (XAs Int32) X * 2 'H è il doppio di 3 Dim HAs Int32 = DoubleIt(3) Console.WriteLine(H) Console.ReadKey()End Sub End Module1
Questo è un esempio più complesso:DoubleIt( Function ByVal XAs Int32)As Int32Return X * 2End Function
Le espressioni lambda possono elaborare qualsiasi tipo di dato, come tutte le altre funzioni. Il loro funzionamento è simile a quello dei delegate: anzi, il concetto è lo stesso.Module Module1Sub Main() 'Questa espressione lambda calcola il Delta di un'equazione 'di secondo grado. Per più parametri, bisogna specificarne 'il tipo per ognuno. La motivazione verrà esposta in seguito Dim Delta =Function (AAs Int32, BAs Int32, CAs Int32) _ B * B - 4 * A * C 'Questa calcola la prima soluzione dell'equazione, con i dati 'coefficienti, facendo uso di delta Dim Soluzione1 =Function (AAs Int32, BAs Int32, CAs Int32) _ (-B + Math.Sqrt(Delta(A, B, C))) / (4 * A) 'E questa la seconda Dim Soluzione2 =Function (AAs Int32, BAs Int32, CAs Int32) _ (-B - Math.Sqrt(Delta(A, B, C))) / (4 * A) 'I coefficienti dell'equazione Dim cA, cB, cCAs Int32 Console.WriteLine("Data ax2 + bx + c = 0") Console.WriteLine() Console.Write("Inserire a: ") cA = Console.ReadLine Console.Write("Inserire b: ") cB = Console.ReadLine Console.Write("Inserire c: ") cC = Console.ReadLine 'Due soluzioni If Delta(cA, cB, cC) > 0Then Console.Write("Due soluzioni: {0} e {1}", _ Soluzione1(cA, cB, cC), Soluzione2(cA, cB, cC))ElseIf Delta(cA, cB, cC) = 0Then Console.Write("Due soluzioni coincidenti: {0}", _ Soluzione1(cA, cB, cC))Else Console.Write("Nessuna soluzione reale.")End If Console.ReadKey()End Sub End Module
Fino ad ora ho fatto esempi che prendevano un oggetto Func e lo usavano così com'era stato creato, ma la loro versatilità sta nel poter essere assegnati e cambiati a piacimento. Prima di vedere un esempio a questo riguardo, bisogna entrare un po' più nel dettaglio ed analizzare come realmente è costituita un'espressione lambda. Essa non è niente altro che un tipo generic, i cui tipi generic collegati definiscono i tipi dei parametri e del valore restituito. Ad esempio:
Questo codice definisce un oggetto Func che accetta un membro di tipo Integer e restituisce un valore Boolean. Pertanto saranno valide le seguenti assegnazioni:Dim PAs Func(Of Integer ,Boolean )
'Mentre verranno segnalate come contenenti errori queste istruzioni:Controlla se A sia maggiore di zero P =Function (AAs Int32) (A > 0) 'Controlla che A sia un numero pari P =Function (AAs Integer) (AMod 2 = 0)
'Dopo aver osservato la struttura intrinseca di un oggetto Func, ecco un esempio in cui sono presenti assegnazioni multiple:Tenta di restituire il doppio di A. Il valore 'restituito deve essere un Boolean, quindi A*2 non costituisce 'un risultato valido P =Function (AAs Int32) A * 2
Prima di concludere, vorrei porre l'attenzione sull'uso nidificato di espressioni lambda. Ecco un esempio:Module Module1Sub Main() 'Considera una generica operazione che elabora due dati 'di tipo Single e restituisce un risultato dello stesso tipo. 'In questo caso va dichiarata esplicitamente la signature 'di Func poiché il compilatore potrebbe erroneamente 'assegnare un altro tipo al valore restituito Dim OpAs Func(Of Single ,Single ,Single ) 'Il segno dell'operazione Dim SignAs Char Console.WriteLine("Inserire un qualsiasi segno di operazione aritmetica:") Sign = Console.ReadLineSelect Case SignCase "+" 'Imposta Op come somma di reali Op =Function (AAs Single , BAs Single ) A + BCase "-" 'Imposta Op come differenza di reali Op =Function (AAs Single , BAs Single ) A - BCase "*" 'Imposta Op come prodotto di reali Op =Function (AAs Single , BAs Single ) A * BCase "/" 'Imposta Op come rapporto di reali Op =Function (AAs Single , BAs Single ) A / BEnd SelectDim X, YAs Single Console.Write("Inserire il primo operando: ") X = Console.ReadLine Console.Write("Inserire il secondo operando: ") Y = Console.ReadLine Console.WriteLine("Risultato: {0}", Op(X, Y)) Console.ReadKey()End Sub End Module
Dim MultAs Func(Of Single , Func(Of Single ,Single )) = _Function (AAs Single ) _Function (BAs Single ) A * B 'Mult accetta un parametro Single e restituisce un'espressione 'lambda secondaria. Questa accetta a sua volta un parametro Single 'e restituisce un Single. Alla fine, il valore restituito 'sarà di tipo Single ed equivarrà al prodotto di A*B
N.B.: dato che le espressioni lambda sono, in conclusione, dei delegate, è possibile utilizzarle al posto di queste come parametri di metodi che accettano delegate con signature identica.
The Totem's Lair - Copyright (C) 2009
È vietata la riproduzione sia totale che parziale del sito.



