Używanie wariancji w delegatach (C#)

Podczas przypisywania metody do delegata kowariancja i kontrawariancja zapewniają elastyczność dopasowania typu delegata z podpisem metody. Kowariancja zezwala metodzie na zwracanie typu, który jest bardziej pochodny niż zdefiniowany w delegatu. Kontrawariancja zezwala na metodę, która ma typy parametrów, które są mniej pochodne niż te w typie delegata.

Przykład 1: Kowariancja

opis

W tym przykładzie pokazano, jak delegaty mogą być używane z metodami, które mają typy zwracane pochodzące z typu zwracanego w podpisie delegata. Typ danych zwracany przez DogsHandler jest typu Dogs, który pochodzi z Mammals typu zdefiniowanego w delegatu.

Kod

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

Przykład 2. Kontrawariancja

opis

W tym przykładzie pokazano, jak delegaty mogą być używane z metodami, które mają parametry, których typy są podstawowymi typami parametrów sygnatury delegata. W przypadku kontrawariancji można użyć jednej procedury obsługi zdarzeń zamiast oddzielnych procedur obsługi. W poniższym przykładzie użyto dwóch delegatów:

W przykładzie zdefiniowano program obsługi zdarzeń z parametrem EventArgs i używa go do obsługi zarówno zdarzeń, jak Button.KeyDown i Button.MouseClick . Może to zrobić, ponieważ EventArgs jest podstawowym typem zarówno , jak KeyEventArgs i MouseEventArgs.

Kod

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

Zobacz też