Una forma de pensar en un delegado es como una referencia a una función. Por ejemplo, supongamos que tiene un botón en una ventana y desea que ocurra algo cuando se hace clic en el botón. Puede adjuntar un delegado al evento Click del botón, y cada vez que el usuario haga clic en este botón, se ejecutará su función.
class MyWindow : Window
{
Button _button;
public MyWindow()
{
_button = new Button();
// place the button in the window
_button.Click += MyWindow.ButtonClicked;
}
static void ButtonClicked(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button Clicked");
}
}
Observe cómo hago ButtonClicked una función estática - Quiero hacer un punto sobre las funciones no estáticas a continuación.Supongamos en cambio que buttonClicked es un miembro no estático:
class MyWindow : Window
{
Button _button;
int _numClicked = 0;
public MyWindow()
{
this._button = new Button();
// place the button in the window
this._button.Click += this.ButtonClicked;
}
void ButtonClicked(object sender, RoutedEventArgs e)
{
this._numClicked += 1;
MessageBox.Show("Button Clicked " + this._numClicked + " times");
}
}
Ahora el delegado contiene una referencia a la función "buttonClicked" y el ejemplo, "este", que se llama al método sobre. La instancia "this" en el constructor MyWindow y "this" en ButtonClicked son iguales.
Este es un caso específico de un concepto conocido como cierres que permite "guardar" el estado - el objeto actual, las variables locales, etc. - al crear un delegado. En el ejemplo anterior, usamos "this" del constructor en el delegado. Podemos hacer más que eso:
class MyWindow : Window
{
Button _button;
int _numClicked = 0;
public MyWindow(string localStringParam)
{
string localStringVar = "a local variable";
this._button = new Button();
// place the button in the window
this._button.Click += new RoutedEventHandler(
delegate(object sender, RoutedEventArgs args)
{
this._numClicked += 1;
MessageBox.Show("Param was: " + localStringParam +
" and local var " + localStringVar +
" button clicked " + this._numClicked + " times");
});
}
}
Aquí hemos creado un delegado anónimo - una función que no se le da un nombre explícito. La única forma de referirse a esta función es usar el objeto delegado RoutedEventHandler. Además, esta función existe en el ámbito del constructor MyWindow, por lo que puede acceder a todos los parámetros locales, variables y la instancia miembro "this". Continuará manteniendo referencias a las variables y parámetros locales incluso después de que el constructor MyWindow salga.
Como nota al margen, el delegado también mantendrá una referencia a la instancia del objeto - "esto" - incluso después de que se eliminen todas las demás referencias a la clase a. Por lo tanto, para garantizar que una clase es basura, todos los delegados a un método miembro no estático (o delegados creados en el alcance de uno) deben ser eliminados.
Puede aclarar: ¿está preguntando sobre cómo usar delegados, o está preguntando cómo C# hace posible a los delegados? – Anton
¡Su pregunta no está clara! ¿Puedes hacerlo más claro? –