Extension methods in C# 3.0

 
09 december 2007

Een zeer mooie nieuwe feature van C# 3.0 stelt je in staat methoden toe te voegen aan bestaande classes. Zo kan je bijvoorbeeld de String, Int en DateTime classes uibreiden. In combinatie met de nieuwe manier van method passing in de vorm van Func<T> stelt je dit mooie dingen in staat.

Stel, ik wil de int uibreiden met een methode “Times”, die ik een method pointer kan meegeven. Zodra ik dan het statement 5.Times(DoSomething); gebruik wordt mijn methode DoSomething vijf keer uitgevoerd. Dit is te bereiken door het toevoegen van de volgende code in een static class in een toegankelijke namespace:

   1: public static void Times(this int i, Func<bool> t)
   2: {
   3:     for (int a = 0; a < i; a++)
   4:         t.Invoke();
   5: }

Niet erg ingewikkeld, toch? Wat kunnen we hier nog meer mee… Smalltalk-achtige constructies springen in gedachten. Je zou het zo kunnen maken dat je if, while en andere taal-specifieke constructies niet meer nodig hebt. Laten we als voorbeeld het bekende if-statement nemen. Smalltalk bevat geen if-statement. Ik ben geen kenner op smalltalk gebied, maar een enthousiaste collega heeft ons laatst wat laten zien waardoor ik toch wel vrij jaloers ben op de eenvoud en puurheid van deze taal. Nu ben ik in de praktijk toch iets meer met .NET en C# bezig, dus laat ik deze mogelijkheid aangrijpen een stukje smalltalk na te bouwen in C#. Conditionele uitvoering van codeblokken geschiedt in Smalltalk als methode van de boolean class. Deze bevat een IfTrue() en IfFalse() methode; de code die ik dus wil laten werken is als volgt.

   1: (5 == 5).IfTrue(DoSomethingElse);

Zo gezegd zo gedaan. Ik voeg de volgende static methode toe aan mijn toegankelijke class en bovenstaande regel werkt!

   1: public static void IfTrue(this bool b, Func<bool> t)
   2: {
   3:     if (b)
   4:         t.Invoke();
   5: }

Nou wil ik dingen altijd zien werken, maar ik vind het ook wel leuk om zaken over the top te brengen. Bovenstaande voorbeeldjes zijn erg leuk en ik zou zeggen laat ze je inspireren om hier iets mee te doen (je kunt je eigen taal gaan schrijven nu :) ). Wat mij echte nog te binnen schoot was een extension op de Func<T> class. Ik zou graag op Functie een methode aanroepen die deze functie herhaalt tot een bepaalde conditie (andere functie) waar is. De toepassing weet ik nog niet, maar ik wil hem je niet onthouden:

   1: (new Func<bool>(IncrementA)).RepeatUntil(A_Equals_B);

IncrementA() wordt nu uitgevoerd totdat A_Equals_B() true geeft. Tja, is dit handig? Ik weet het niet. Zo doe je het in elk geval:

   1: public static void RepeatUntil(this Func<bool> f, Func<bool> f2)
   2: {
   3:     while (!f2.Invoke())
   4:         f.Invoke();
   5: }

Interesse om deze wondercode aan het werk te zien? Download het dan hier. Tevens ben ik erg benieuwd naar andere toepassingen van deze extension methods in de praktijk.


Werken met ?
Kijk dan bij onze mogelijkheden voor starters en/of ervaren IT'ers.


Categorieën: Development

Tags: ,


Reacties (2)

  • Arno den Uijl schreef:

    In plaats van System.Func kun je in veel gevallen wellicht gebruik maken van System.Action. Dan hoef je niet geforceerd een return value op te geven.

    Geplaatst op 19 december 2007 om 1:33 Permalink

  • Jaap Taal schreef:

    Voor de mensen die net als ik niet weten wat de Func delegate is, zie deze pagina

    Deze extended methods zijn een onwijs mooie feature in de taal.

    Volgens mij zijn de toepassingen van Extension Methods essentieel voor LINQ.
    In de System.Linq.Enumerable klasse zijn veel Extension Methods gedefinieerd voor IEnumerable objecten. Een van de methoden die je denk ik veel kunt gebruiken is de Where methode. Deze kan een IEnumerable filteren. Samen met lambda expressies is dit super krachtig!

    string[] lijst = { “aap”, “noot”, “mies”, “noot2” };
    foreach (string str in lijst.Where(str => str.StartsWith(“n”)))
    {
    Console.WriteLine(str);
    }

    Op de MSDN site vind je een overzicht van de methoden die je op een IEnumerable kan gebruiken.

    Geplaatst op 14 december 2007 om 17:55 Permalink

Trackback & Pingback (1)

  1. Van Sogyo lanceert software-innovators.nl | Sogyo op 18 december 2007 at 12:34

    […] voor artikelen kun je verwachten? Hieronder een greep uit de recente postings: Extension methods in C# 3.0, Generic Collections, Enterprise Software Development: Confusion about Internal DSLs of […]