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;  
  
}  

Vedi anche