Articoli di programmazione

Delegates, Anonymous Methods e Lambda Expressions: facciamo chiarezza

Esaminiamo con dei semplici esempi pratici in cosa consistono le differenze tra questi elementi del linguaggio C#

images.png
E' importante capire come sfruttare i Delegates, in tutte le loro declinazioni sintattiche per sfruttare al massimo la flessibilità del linguaggio C#.
Ecco di seguito alcuni Test scritti per MSTest, che mostrano in un semplice percorso, come la stessa funzione possa essere scritta in modi differenti e raggiunga sempre lo stesso risultato.

Per prima cosa definiamo la nostra classe di Test, con un #Delegate SomeMethodDelegate che accetta un Intero in input e ne restituisce uno in output; definiamo poi un metodo che ne ricalca la firma SomeMethod, in modo che possa corrispondere alla definizione richiesta dal Delegate ed essere quindi richiamato da esso:

[TestClass]
public class DelegateExamples
{
private delegate Int32 SomeMethodDelegate(Int32 input);
public static Int32 SomeMethod(Int32 input)
{
return input + 1;
}
}


Nel primo esempio ci limitiamo ad eseguire SomeMethodDelegate nel modo più prolisso, quello standard a cui sono abituati i veterani del linguaggio:

[TestMethod]
public void StandardDelegateTest()
{
SomeMethodDelegate f = new SomeMethodDelegate(DelegateExamples.SomeMethod);
Int32 y = f(5);

y.Should().Be.EqualTo(6);
}

Nel secondo esempio applichiamo una piccola scorciatoia, dato che il metodo SomeMethod è incluso nella stessa classe di esecuzione:

[TestMethod]
public void StandardShortDelegateTest()
{
SomeMethodDelegate f = SomeMethod;
Int32 y = f(5);

y.Should().Be.EqualTo(6);
}

Adesso vediamo come scrivere il codice equivalente tramite una funzione anonima, quindi non facendo più uso della funzione SomeMethod dichiarata sopra:

[TestMethod]
public void AnonymousTest()
{
SomeMethodDelegate f = delegate(Int32 x) { return x + 1; };
Int32 y = f(5);

y.Should().Be.EqualTo(6);
}

Beh a questo punto possiamo fare a meno anche della dichiarazione del #Delegate ed utilizzare una semplice Func al suo posto:

[TestMethod]
public void AnonymousFuncTest()
{
Func<Int32, Int32> f = delegate(Int32 x) { return x + 1; };
Int32 y = f(5);

y.Should().Be.EqualTo(6);
}

Per non farci mancare niente, usiamo quindi una #Lambda al posto del Delegate, in modo da risparmiare ulteriormente tempo di scrittura e soprattutto rendere tutto più immediato da leggere e comprendere:

[TestMethod]
public void LambdaFuncTest()
{
Func<Int32, Int32> f = x => { return x + 1; };
Int32 y = f(5);

y.Should().Be.EqualTo(6);
}


Piccola nota: la sintassi Fluent nei test è stata implementata da SharpTestEx (https://www.nuget.org/packages/SharpTestsEx/)

#programmazione #delegates #csharp