Covariance allows that we can assign it a method that has a "more derived return type" than the "originally specified return type."
contravariance allows a method with parameter types that are less derived than in the delegate type.
In the following code we can do the following assignment
ShowVehicleTypeDelegate del2 = bus1.ShowBus;
Although our delegate return type was Vehicle, its del2 object received a derived type "Bus" object.
using System; delegate Vehicle ShowVehicleTypeDelegate(); class Vehicle/*from w w w. j ava2 s . c om*/ { public Vehicle ShowVehicle() { Vehicle myVehicle = new Vehicle(); Console.WriteLine(" A Vehicle created"); return myVehicle; } } class Bus : Vehicle { public Bus ShowBus() { Bus myBus = new Bus(); Console.WriteLine(" A Bus created"); return myBus; } } class Program { static void Main(string[] args) { Vehicle vehicle1 = new Vehicle(); Bus bus1 = new Bus(); ShowVehicleTypeDelegate del1 = vehicle1.ShowVehicle; del1(); //Note that it is expecting a Vehicle(i.e. a basetype) but received a Bus(subtype) //Still this is allowed through Covariance ShowVehicleTypeDelegate del2 = bus1.ShowBus; del2(); } }