Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Tuesday, August 11, 2009

Covariance and Contravariance in Delegates

Covariance and contravariance provide a degree of flexibility when matching method signatures with delegate types.

Covariance -> permits a method to have a more derived return type than what is defined in the delegate.

Contravariance -> permits a method with parameter types that are less derived than in the delegate type.

Example 1 (Covariance)
This example demonstrates how delegates can be used with methods that have return types that are derived from the return type in the delegate signature. The data type returned by SecondHandler is of type Dogs, which derives from the Mammals type that is defined in the delegate.

C#
class Mammals
{
}

class Dogs : Mammals
{
}

class Program
{
// Define the delegate.
public delegate Mammals HandlerMethod();

public static Mammals FirstHandler()
{
return null;
}

public static Dogs SecondHandler()
{
return null;
}

static void Main()
{
HandlerMethod handler1 = FirstHandler;

// Covariance allows this delegate.
HandlerMethod handler2 = SecondHandler;
}
}
Example 2 (Contravariance)
This example demonstrates how delegates can be used with methods that have parameters of a type that are base types of the delegate signature parameter type. With contravariance, you can now use one event handler in places where, previously, you would have had to use separate handlers. For example, you can now create an event handler that accepts an EventArgs input parameter and use it with the Button.MouseClick event that sends a MouseEventArgs type as a parameter, and also with TextBox.KeyDown event that sends a KeyEventArgs parameter.

C#
System.DateTime lastActivity;
public Form1()
{
InitializeComponent();

lastActivity = new System.DateTime();
this.textBox1.KeyDown += this.MultiHandler; //works with KeyEventArgs
this.button1.MouseClick += this.MultiHandler; //works with MouseEventArgs

}

// Event hander for any event with an EventArgs or
// derived class in the second parameter
private void MultiHandler(object sender, System.EventArgs e)
{
lastActivity = System.DateTime.Now;
}


Source : MSDN

Wednesday, May 7, 2008

Events in C#

(Notes from HFC#)

Steps in Event execution
1)We need an event for event arguments

eg-> public class BallEventArgs : EventArgs

=> EventArgs is an empty class.It has no public members.Its sole purpose is to allow
your event arguments to be passed to the event handlers that use it .

2)Need to define the event in the class that'll raise it .

eg-> public event EventHandler BallInPlay

=>after EVENT keyword comes EVENTHANDLER.It is needed to tell object subscribing to event that
their event handlers need to take 2 parameters,an object named SENDER and an EVENTARGS reference names e,
and have no return value(void).

3)The subscribing classes need EventHandler methods

eg-> void ball_BallInPlay(object sender,EventArgs e )

=>Standard Naming Convention for EventHandlers -> NameOfObjectReference,followed by UNDERSCORE ,followed by
NameOfEvent.

4)Each individual object subscribes to the event

eg-> ball.BallInPlay += new EventHandler(ball_BallInPlay)

=>The += EVENT tells C# subscribe an event handler to an event.

5)A Ball Object raises its event to notify subscribers that it's in play

ex- if (BallInPlay !=null) BallInPlay(this,e)

Note: If you raise an event with no handlers ,it'll throw an exception.