2010-08-17 5 views
6

List<T>.Sort() método tiene 3 sobrecargas.System.Comparison <T> comprensión

Uno de ellos es el siguiente

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

Al ver Comparison<T>, pensé que debería ser una clase que se deriva de Comparison<T> clase. (Una interpretación habitual de los parámetros)

Pero lo siguiente funciona muy bien y se dice que está utilizando la sobrecarga anterior.

 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()); 
     } 

me hicieron dar un delegado a un método estático en lugar de Comparison<T>. ¿Cómo funciona?

+1

por favor no etiquetar a tus preguntas" .net2.0 "a menos que sean específicos de .NET 2.0. –

+0

No entiendo por qué John Saunders no quiere que esto sea etiquetado como .NET 2.0, ya que esta pregunta no es aplicable a .NET 1.1 o anterior. Y con qué frecuencia alguien tiene una pregunta que solo se aplica a una versión de .NET. Por lo general, una pregunta se aplica a una versión y a todas las versiones más recientes. –

Respuesta

9

System.Comparison<T> se define de la siguiente manera:

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

Eso significa que es delegate no una clase Un método que acepta un delegado como parámetro acepta realmente un método, no una instancia de una clase de Comparación.

Este código se puede reescribir de la siguiente manera con una expresión lambda:

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

El siguiente fragmento podría explicar mejor lo que sucede:

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()); 
    } 
} 
1

System.Comparison<T>es un delegado.

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

La firma de su método CompareWithCase hace que sea perfectamente asignables a Comparison<int>.

Tenga en cuenta que sin tipo de inferencia, su llamada Sort habría tenido que ser escrito como:

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

FYI, Los otros 2 sobrecargas de List<T>.Sort esperan IComparer<T> implementaciones