Delegates mit .NET

Unterschiede zu Funktionszeigern

Wer einen C/C++-Hintergrund hat, dem wird das sehr bekannt vorkommen: Es funktioniert wie die Verwendung von Zeigern auf Funktionen - und so ist es auch. Allerdings bieten Delegates mehr als nur Zeiger auf Funktionen.

Die Methode aus LogHelper schreibt momentan einfach auf die Konsole. Will man in eine Datei schreiben, dann muss die Information über die zu verwendende Datei natürlich auch noch irgendwo herkommen. In C würde man noch zusätzliche Informationen in einem anderen Zeiger übergeben - zum Beispiel ein Filehandle oder den Namen der Datei.

In C# kann man aber bei Delegates sowohl statische Methoden als auch ganz normale Methoden verwenden, und das bedeutet, das man auf die Informationen des umgebenden Objekts zugreifen kann. Das erweiterte Muster, in dem dann in eine Datei geschrieben wird, hat beispielsweise folgendes Aussehen:

public class LogHelper {
// methode 1
static void LogToConsole( string s) {
Console.WriteLine( s);
}

// methode 2
FileStream stream;
StreamWriter writer;

public LogHelper( string filename) {
stream = new FileStream( filename, FileMode.Create);
writer = new StreamWriter( stream);
}

public void LogToFile( string s) {
writer.WriteLine( s);
}

public void End() {
writer.Close();
stream.Close();
}
}

class Worker {
public static void Main() {
AClass a = new AClass();
LogHelper lh = new LogHelper( "logfile.log");
AClass.Logger log = new AClass.Logger( lh.LogToFile);
a.DoIt( log);
lh.End();
}
}

Hier kapselt die LogHelper-Klasse also auch die Datei, in die geschrieben werden soll. Der Delegate zeigt dann auf die normale Member-Funktion von LogHelper und nicht länger auf die statische Methode dieser Klasse. Wird DoIt dann aufgerufen, so landet die Log-Information in der gewünschten Datei.

Hier sieht man auch einen sehr praktischen Effekt, der bei der Verwendung von Delegates auftritt: Die Implementierung von DoIt musste nicht verändert werden, obwohl die darin verwendete Log-Funktionalität sich sehr stark von der ursprünglichen unterscheidet.