Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Comparison<T> understanding

Tags:

.net

List<T>.Sort() method has 3 overloads.

One of them is the following

System.Collections.Generic.List<T>.Sort(System.Comparison<T>)

On seeing Comparison<T>, I thought that it should be a class which is derived from Comparison<T> class. (An usual interpretation on the parameters)

But the following works really well and said to be using the above overload.

        public static void Main(string[] args)
        {
            List<Int32> collection = new List<Int32>();

            collection.Add(20);
            collection.Add(270);
            collection.Add(30);
            collection.Add(90);
            collection.Add(40);
            collection.Add(18);
            collection.Add(100);

            collection.Sort(MyComparer.CompareWithCase);

            foreach (Int32 s in collection)
                Console.WriteLine(s);
        }

        public static int CompareWithCase(int i1, int i2)
        {
            return i1.ToString().CompareTo(i2.ToString());
        }

I did give a delegate to a static Method in place of Comparison<T>. How does it work?

like image 941
SaravananArumugam Avatar asked Aug 17 '10 02:08

SaravananArumugam


2 Answers

System.Comparison<T> is defined as follows:

public delegate int Comparison<in T>(T x, T y);

That means that it's delegate, not a class. A method accepting a delegate as a parameter actually accepts a method, not an instance of a Comparison class.

This code can be rewritten as follows with a lambda expression:

collection.Sort((i1, i2) => i1.ToString().CompareTo(i2.ToString()));

The following snippet might explain better what happens:

public static class TestClass {

  public static void Main(string[] args){
      Comparison<Int32> comparisonDelegate = CompareWithCase;
      //We now can use comparisonDelegate as though it is a method;
      int result = comparisonDelegate(1,2);
  }

  public static int CompareWithCase(int i1, int i2)
  {
     return i1.ToString().CompareTo(i2.ToString());
  } 
}
like image 135
Igor Zevaka Avatar answered Sep 20 '22 11:09

Igor Zevaka


System.Comparison<T> is a delegate.

public delegate int Comparison<in T>(
    T x,
    T y
)

The signature of your CompareWithCase method makes it perfectly assignable to Comparison<int>.

Note that without type-inferencing, your Sort call would have had to be written as:

 collection.Sort(new Comparison<int>(MyComparer.CompareWithCase));

FYI, The other 2 overloads of List<T>.Sort expect IComparer<T> implementations

like image 37
Ani Avatar answered Sep 22 '22 11:09

Ani