You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/csharp/programming-guide/concepts/covariance-contravariance/using-variance-in-delegates.md
+23-25Lines changed: 23 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -51,43 +51,41 @@ class Program
51
51
52
52
This example demonstrates how delegates can be used with methods that have parameters whose types are base types of the delegate signature parameter type. With contravariance, you can use one event handler instead of separate handlers. The following example makes use of two delegates:
53
53
54
-
- A <xref:System.Windows.Forms.KeyEventHandler> delegate that defines the signature of the [Button.KeyDown](xref:System.Windows.Forms.Control.KeyDown) event. Its signature is:
54
+
- A custom `KeyEventHandler` delegate that defines the signature of a key event. Its signature is:
- A <xref:System.Windows.Forms.MouseEventHandler> delegate that defines the signature of the [Button.MouseClick](xref:System.Windows.Forms.Control.MouseDown) event. Its signature is:
60
+
- A custom `MouseEventHandler` delegate that defines the signature of a mouse event. Its signature is:
61
61
62
62
```csharp
63
63
public delegate void MouseEventHandler(objectsender, MouseEventArgse)
64
64
```
65
65
66
-
The example defines an event handler with an <xref:System.EventArgs> parameter and uses it to handle both the `Button.KeyDown` and `Button.MouseClick` events. It can do this because <xref:System.EventArgs> is a base type of both <xref:System.Windows.Forms.KeyEventArgs> and <xref:System.Windows.Forms.MouseEventArgs>.
66
+
The example defines an event handler with an <xref:System.EventArgs> parameter and uses it to handle both key and mouse events. This works because <xref:System.EventArgs> is a base type of both the custom `KeyEventArgs` and `MouseEventArgs` classes defined in the example. Contravariance allows a method that accepts a base type parameter to be used for events that provide derived type parameters.
67
+
68
+
### How contravariance works in this example
69
+
70
+
When you subscribe to an event, the compiler checks if your event handler method is compatible with the event's delegate signature. With contravariance:
71
+
72
+
1. The `KeyDown` event expects a method that takes `KeyEventArgs`.
73
+
1. The `MouseClick` event expects a method that takes `MouseEventArgs`.
74
+
1. Your `MultiHandler` method takes the base type `EventArgs`.
75
+
1. Since `KeyEventArgs` and `MouseEventArgs` both inherit from `EventArgs`, they can be safely passed to a method expecting `EventArgs`.
76
+
1. The compiler allows this assignment because it's safe - the `MultiHandler` can work with any `EventArgs` instance.
77
+
78
+
This is contravariance in action: you can use a method with a "less specific" (basetype) parameter where a "more specific" (derivedtype) parameter is expected.
67
79
68
80
### Code
69
-
70
-
```csharp
71
-
// Event handler that accepts a parameter of the EventArgs type.
When you run this example, you'll see that the same `MultiHandler` method successfully handles both key and mouse events, demonstrating how contravariance enables more flexible and reusable event handling code.
0 commit comments