Tuesday, March 20, 2012

Implementing IComparer Interface

We discussed IComparable interface in previous post and touched a bit on IComparer interface. IComparable interface only compares two objects of the same type and the class must implement IComparable interface. But what if you have two different objects that you want to compare, or what if you want to compare the same object, but the class doesn't implement ICmparable interface?

IComparer interface provides additional methods of comparing the objects. For example, we can sort a class based on multiple properties or fields.

This interface implements a method called "Compare()" which takes two object parameters and returns an integer value like "CompareTo()" method.

Let's use the same example like we used in previous post but this time we will use "IComparer" interface.

Order Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ComparableInterface
{
    class Orders
    {
        public int orderID { get; set; }
        public DateTime orderDate { get; set; }
        public int quantity { get; set; }
        public int customerID { get; set; }
        public string customerName { get; set; }
        public Status OrderStatus { get; set; }
           

    }
}

Three classes implementing "Compare" method
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ComparableInterface
{
    class OrderCompare:IComparer<Orders>
    {
        
        //you must implement Compare method declared in IComparable interface
        //sort in ascending order
        public int Compare(Orders order1, Orders order2)
        {
            if (order1.orderID > order2.orderID) return 1;
            else if (order1.orderID < order2.orderID) return -1;
            else return 0;
        }

    }
    class OrderCompare2:IComparer<Orders>
    {
        //but you can implement overloaded signature
        //sort in descending order
        public int Compare(Orders order1, Orders order2)
        {
            if (order1.orderID < order2.orderID) return 1;
            else if (order1.orderID > order2.orderID) return -1;
            else return 0;
        }
    }
    class OrderCompare3 : IComparer<Orders>
    {
        //sort by different field - string sort
        public int Compare(Orders order1, Orders order2)
        {
            return string.Compare(order1.customerName,order2.customerName);
        }
    }
}


Using the Sort Method
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ComparableInterface
{
    class Program
    {
        
        static void Main(string[] args)
        {

            //Let's create a collection of orders and then sort them.
            List<Orders> orderlist = new List<Orders>
            {
                new Orders{orderID=100,orderDate=DateTime.Today,
                           quantity=5,customerID=10,
                           customerName="Second User",OrderStatus=Status.placed},
                new Orders{orderID=90,orderDate=DateTime.Today,
                           quantity=15,customerID=20,
                           customerName="First User",OrderStatus=Status.placed}
            };
            //let's not sort it
            foreach (Orders order in orderlist)
            { Console.WriteLine("Order ID:{0}", order.orderID); }

            Console.WriteLine(Environment.NewLine);

            //now sort using 1st comparer
            Console.WriteLine("Sort Using Order ID - Ascending");
            OrderCompare ordersort = new OrderCompare();
            orderlist.Sort(ordersort);
           foreach (Orders order in orderlist)
            { Console.WriteLine("Order ID:{0}, CustomerName{1} ", 
                                 order.orderID,order.customerName); }

           Console.WriteLine(Environment.NewLine);
           //now sort using end comparer
           Console.WriteLine("Sort Using Order ID - Descending");
           OrderCompare2 ordersort2 = new OrderCompare2();
           orderlist.Sort(ordersort2);
           foreach (Orders order in orderlist)
           { Console.WriteLine("Order ID:{0}, CustomerName{1} ", 
                                order.orderID, order.customerName); }

           Console.WriteLine(Environment.NewLine);
           //now sort using end comparer
           Console.WriteLine("Sort Using Customer Name");
           OrderCompare3 ordersort3 = new OrderCompare3();
           orderlist.Sort(ordersort3);
           foreach (Orders order in orderlist)
           { Console.WriteLine("Order ID:{0}, CustomerName{1} ", 
             order.orderID, order.customerName); }

            Console.Read();

        }
    }
}

Compare method allows you to compare two objects even if they don't implement IComparer interface. You simply pass an instance of the class implementing this interface to the Sort method.

Thank you.

No comments:

Post a Comment