Uso della varianza nei delegati (C#)
Quando si assegna un metodo a un delegato, covarianza e controvarianza offrono flessibilità per la corrispondenza di un tipo delegato con una firma di metodo. La covarianza consente a un metodo di avere un tipo restituito più derivato di quello definito nel delegato. La controvarianza consente un metodo con tipi di parametro meno derivati rispetto a quelli del tipo delegato.
Esempio 1: covarianza
Descrizione
In questo esempio viene illustrato in che modo si possono usare i delegati con i metodi che hanno tipi restituiti derivati dal tipo restituito nella firma del delegato. Il tipo di dati restituito da DogsHandler
è di tipo Dogs
, che deriva dal tipo Mammals
definito nel delegato.
Codice
class Mammals {}
class Dogs : Mammals {}
class Program
{
// Define the delegate.
public delegate Mammals HandlerMethod();
public static Mammals MammalsHandler()
{
return null;
}
public static Dogs DogsHandler()
{
return null;
}
static void Test()
{
HandlerMethod handlerMammals = MammalsHandler;
// Covariance enables this assignment.
HandlerMethod handlerDogs = DogsHandler;
}
}
Esempio 2: controvarianza
Descrizione
In questo esempio viene illustrato in che modo si possono usare i delegati con i metodi che hanno parametri i cui tipi rappresentano tipi di base del tipo di parametro della firma del delegato. Con la controvarianza è possibile usare un solo gestore eventi anziché gestori separati. Nell'esempio seguente vengono usati due delegati:
Un delegato KeyEventHandler che definisce la firma dell'evento Button.KeyDown. La firma è:
public delegate void KeyEventHandler(object sender, KeyEventArgs e)
Un delegato MouseEventHandler che definisce la firma dell'evento Button.MouseClick. La firma è:
public delegate void MouseEventHandler(object sender, MouseEventArgs e)
Nell'esempio viene definito un gestore eventi con un parametro EventArgs e viene usato per gestire entrambi gli eventi Button.KeyDown
e Button.MouseClick
. Ciò è possibile perché EventArgs è un tipo di base sia di KeyEventArgs che di MouseEventArgs.
Codice
// Event handler that accepts a parameter of the EventArgs type.
private void MultiHandler(object sender, System.EventArgs e)
{
label1.Text = System.DateTime.Now.ToString();
}
public Form1()
{
InitializeComponent();
// You can use a method that has an EventArgs parameter,
// although the event expects the KeyEventArgs parameter.
this.button1.KeyDown += this.MultiHandler;
// You can use the same method
// for an event that expects the MouseEventArgs parameter.
this.button1.MouseClick += this.MultiHandler;
}