Covariance and contravariance provide a degree of flexibility when you match 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.

contravariance example:

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 handler in places where, previously, you would have had to use separate handlers. For example both sellNotifyDlg and sellBondNotify delegates are using the same handler - EquitySaleReport since both stock and bond derive from Equity base class

using System;
using System.Collections.Generic;
using System.Text;

namespace ContraVariance
{
    //base class
    class Equity
    {
        int _price;

        public Equity(int Price)
        {
            _price = Price;
        }
        public override string ToString()
        {
            return GetType().Name + " : " + _price;
        }
    }
    //derived
    class Stock : Equity
    {
        public Stock(int Price)
            : base(Price)
        {

        }
    }

    //derived
    class Bond : Equity
    {
        public Bond(int Price)
            : base(Price)
        {

        }
    }

    class Program
    {
        delegate void StockSellNotify(Stock s);
        delegate void BondSellNotify(Bond b);

        static void EquitySaleReport(Equity e)
        {
            Console.WriteLine("Report of sale is " + e);
        }

        static StockSellNotify sellNotifyDlg;
        static BondSellNotify sellBondNotify;

        static void Sell(Stock s)
        {
            if (null != sellNotifyDlg)
            {
                sellNotifyDlg(s);
            }
        }

        //overload
        static void Sell(Bond  b)
        {
            if (null != sellBondNotify)
            {
                sellBondNotify(b);
            }
        }
      

        static void Main(string[] args)
        {
            sellNotifyDlg += EquitySaleReport;
            Sell(new Stock(100));

            sellBondNotify += EquitySaleReport;
            Sell(new Bond(101));

            //both sellNotifyDlg and sellBondNotify are using the same handler - EquitySaleReport

           
        }
    }
}

In my next post i will put a sample for Covariance and try to refine the contravariance sample with generics ...

Happy programming !!!

posted on Monday, February 25, 2008 7:45 PM
Filed Under [ BizTalk, WCF, Design Patterns, C#, Software Factories C# general ]
  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati

Comments

No comments posted yet.

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: