Wat je hier beschrijft, is imo erg procedureel gericht (functionele decompositie ensow) en (dus ) niet thuishoren in een OO-language als C#.
Mwah, dat valt wel mee denk ik

. Jij gaf aan dat je in plaats globale variabelen liever werkt met parameters indien mogelijk. Hier valt zeker wat voor te zeggen: over variabelen in een klasse moet je nadenken. Ze ontstaan als het goed is niet uit noodzaak.
Als je (bijvoorbeeld) een bepaalde delegate hebt voor een bepaald event, ben je gedwongen om als parameters object sender en EventArgs e mee te geven en kun je als je extra parameters in je eigen method (eventhandler) nodig hebt, die niet toevoegen.
Dat is inderdaad wat ik bedoel.
Als je zoiets bedoelt, dan zou mijn antwoord daarop zijn: dan maak je een eigen MyEventArgsClass die je afleidt van EventArgs; definieer je daar een constructor met de parameters die je nodig hebt en zet je die parameters als property van je MyEventArgsClass.
Maar dit is niet de oplossing: je hebt zelf namelijk helemaal geen invloed op de inhoud van de EventArgs. De parameters die worden meegegeven worden bij de aanroep van een delegate instantie worden gekozen door het stuk code waaraan je de delegate instantie mee hebt gegeven. Je roept de delegate dus niet zelf aan. De aanroepende code moet dus kennis hebben van de parameters die nodig zijn voor de aanroep van de delegate.
Als je echter 'extra parameters' nodig hebt, is dat een specifieke situatie: slechts 1 mogelijke toepassing van de delegate en de code die de delegate gebruikt. Je kan hierin op dit moment alleen maar via klasse variabelen 'extra parameters' meegeven aan de delegate. Je zou deze extra parameters best kunnen toevoegen aan de delegate en de code die de delegate aanroept, maar dan moet die code dus wel kennis hebben van deze specifieke situatie en worden andere situaties uitgesloten.
Via de anonieme methode met lexical scope ontstaat er een nieuwe manier om extra variabelen te gebruiken de methode die zal worden aangeroepen. Je hoeft dit nu niet meer percee via klasse variabelen te doen: de anonieme methode kan ook gebruik maken van de lokale variabelen van de methode waarin de anonieme methode zich bevindt.
Daarom lost het dus echt iets op en dus voegt het niet alleen gemak toe, maar maakt wellicht zelfs af en toe op kleine schaal een beter design mogelijk.
Als je iets anders bedoelt, zou je dan misschien een concreet voorbeeld (*) kunnen geven, waarbij er echt een duidelijk voordeel is voor het gebruiken van anonymous methods? (Of een nadeel, omdat je geen anonymous method kunt gebruiken.)
Je kan de situatie heel goed vergelijken door de delegates vol uit te programmeren in Java: je ziet dan precies op welke manieren je parameter mee kan geven aan de functie en waarom de lexical scope dus iets toevoegt. Je moet dan namelijk zelf de declaratie van de gebruikte variabelen regelen en dan zie je precies wat er gebeurt.
Het lijkt allemaal wat simpel, maar als je het goed bekijkt wordt de situatie precies duidelijk.
Stel dat je deze onzinnige interface hebt:
Java:
1
2
3
| public interface Add {
public int apply(int value);
} |
Je ziet natuurlijk wel de gelijkenis met een gewone methode: het is in feite gewoon een methode die we bekijken als een klasse. De interface is daarom 1 op 1 te vergelijken met een delegate declaratie in C# :
C#:
1
| public delegate int Add(int value); |
Een implementatie van de Java interface Add zou een bepaald getal (niet gedefinieerd welke) op moeten tellen bij de value en het resultaat opleveren. Een mogelijke implementatie is dus deze:
Java:
1
2
3
4
5
| public class Increment implements Add {
public int apply(int value) {
return value + 1;
}
} |
Een implementatie van de C# delegate Add is bijvoorbeeld deze methode:
C#:
1
2
3
| public int Increment(int value) {
return value + 1;
} |
Van de Add delegate kan je zo een instantie aanmaken met de methode Increment:
C#:
1
| Add increment = new Add(Increment); |
Van de Java klasse Increment kan je zo een instantie maken, die je uiteraard kan behandelen als 'een Add' :
Java:
1
| Add increment = new Increment(); |
Stel nu echter dat we een generieke implementatie van de Add willen maken, die een getal x optelt bij de geven value. De Java klasse Increment kunnen we hier voor gebruiken als basis.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
| public class GenericAdd implements Add {
private int _x;
public GenericAdd(int x) {
super();
_x = x;
}
public int apply(int value) {
return value + x;
}
} |
We hebben dus in de klasse GenericAdd een veld toegevoegd: x. Er was al een klasse (die eerste Increment heette), we hebben nu alleen maar een constructor gemaakt en een veld toegoevoegd. Een instantie aanmaken is simpel: new GenericAdd(5) bijvoorbeeld.
In C# wordt het lastig om de methode Increment aan te passen: we moeten de x meegeven aan de methode, maar hoe?
C#:
1
2
3
| public int GenericAdd(int value) {
return value + x;
} |
Dit kan dus alleen via een nieuw veld in de klasse, die tot nu toe irrelevant was: voor hetzelfde geldt was het zelfs een statische methode. Hierdoor wordt er de oude manier van werken dus eigenlijk onmogelijk en moeten we alleen maar omdat we toevallig die x nodig hebben (een klein beetje) anders gaan werken.
Met de komste van anonieme methoden wordt dit anders: we kunnen de GenericAdd nu definieren als anonieme methode in de construrende methode en deze gebruik laten maken van een lokale variabele. Bijvoorbeeld:
C#:
1
2
3
4
| public void DoSomething() {
int x = 5;
Add addx = new Add(value) { return value + x; };
} |
Let op de code die uiteindelijk met de Add delegate gaat werken, dus niets weet van de x en deze dus niet meegeeft als parameter. Ook hebben we geen klasse variabelen in de onbekende omringende klasse toegevoegd.
Maar in die Java implementatie voel je wel een veld toe? Ja inderdaad, maar het punt is juist dat er daar al een klasse was die nodig was omdat Java geen delegates kent. De aanroepende methode weet ik ook niets van de velden in de implementatie en de velden kunnen geinitialiseerd worden met de lokale variabelen van de methode die de GenericAdd instantie aanmaakt. Het heeft dus wat weg van lexical scope en daarom zou je het ook als anonieme lokale klasse kunnen implementeren:
Java:
1
2
3
4
5
6
7
8
| public void doSomething() {
final int x = 5;
Add addx = new Add() {
public int apply(int value) {
return value + x;
};
} |
Merk op hoe ontzettend veel dit lijkt op de anonieme methode in C# ....
Ik geef direct toe dat het voorbeeld een beetje vaag is: wat heb je nu aan een GenericAdd als deze alleen te gebruiken is in 1 methode?

. Het gaat echter om het idee en dat wordt hier denk ik goed duidelijk.
Ik zou persoonlijk toch gaan voor de duidelijkheid... (en voor OO )
Ik wil hier ook allerminst een pleidooi houden voor delegates, maar als je toch al delegates hebt is de anonieme methode met lexical scope een goede toevoeging

.