2010-06-28 11 views
17

¿Cómo es que las funciones anónimas funcionan como argumentos en los métodos, pero no en los argumentos del constructor?SortedSet <T> y anónimo IComparer <T> en el constructor no funciona


Si creo un List<string>, que tiene un método de ordenación con la siguiente firma:

public void Sort(IComparer<T> comparer) 

en las siguientes obras:

List<string> list = new List<string>(); 
list.Sort((a,b) => a.CompareTo(b)); 

SortedSet tiene un constructor con una firma similares :

public SortedSet(IComparer<T> comparer) 

pero esto falla al usar una función anónima en el constructor. Lo siguiente no es válido:

SortedSet<string> set = new SortedSet<string>((a, b) => a.CompareTo(b)); 

Creación de una clase de clasificación funciona bien como se esperaba:

public class MyComparer : IComparer<string> 
{ 
    public int Compare(string a, string b) 
    { return a.CompareTo(b); } 
} 

SortedSet<string> set = new SortedSet<string>(new MyComparer()); 

Respuesta

27

Eso es porque acepta una the constructor (interfaz) IComparer<T>, en lugar de un Comparison<T> (delegado). Anon-methods/lambdas puede soportar delegados, pero no interfaces (directamente). Es bastante fácil para envolver, aunque - por ejemplo:

class FuncComparer<T> : IComparer<T> 
{ 
    private readonly Comparison<T> comparison; 
    public FuncComparer(Comparison<T> comparison) { 
     this.comparison = comparison; 
    } 
    public int Compare(T x, T y) { 
     return comparison(x, y); } 
} 

Ahora puede utilizar:

SortedSet<string> set = new SortedSet<string>(
     new FuncComparer<string>((a, b) => a.CompareTo(b))); 
+0

Gracias por la explicación y el código del envoltorio. Ahora veo que estaba usando la comparación y no IComparere en el ordenamiento. –

0

que su caso list.sort utiliza esta firma

public void Sort(Comparison<T> comparison) 

pero no este

public void Sort(IComparer<T> comparer) 
18

.NET Framework 4.5 re arrendamiento introdujo el método de fábrica Comparer<T>.Create:

var set = new SortedSet<string>(
    Comparer<string>.Create((a, b) => a.CompareTo(b))); 
+0

¿Qué ocurre si quiero que el conjunto diferencie entre teclas pero ordenadas por valores? – shinzou

0

La explicación es muy bueno que SortedSet acepta una interfaz pero no un delegado (pero Java)..

Debido a eso, los chicos de .Net proporcionan un método de fábrica para crear dicho objeto, por lo que no es necesario definir una nueva clase para eso.

var set = new SortedSet<string>( 
    Comparer<string>.Create((a, b) => a.CompareTo(b)) 
); 
Cuestiones relacionadas