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:
Delegat KeyEventHandler definiujący podpis zdarzenia Button.KeyDown . Jego podpis to:
public delegate void KeyEventHandler(object sender, KeyEventArgs e)
Delegat MouseEventHandler definiujący podpis zdarzenia Button.MouseClick . Jego podpis to:
public delegate void MouseEventHandler(object sender, MouseEventArgs e)
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;
}