2011-05-12 18 views
8

Estoy tratando de eliminar las entradas duplicadas de una lista que contiene un objeto genérico.simple IEqualityComparer <T> pregunta

public class MessageInfo 
{ 
    public DateTime Date { get; set; } 
    public string To { get; set; } 
    public string Message { get; set; } 
} 

public class SMSDupeRemover : IEqualityComparer<MessageInfo> 
{ 
    public bool Equals(MessageInfo x, MessageInfo y) 
    { 
     throw new NotImplementedException(); 
    } 

    public int GetHashCode(MessageInfo obj) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Y el código para eliminar los duplicados:

IEnumerable<MessageInfo> new_texts = text_messages.Distinct(new SMSDupeRemover()); 

El problema es iguales y GetHashCode nunca es llamado. Alguien tiene alguna idea de por qué?

Respuesta

12

Debido Distinct es perezoso. Intente agregar ToList() al final.

Respuesta larga. Las operaciones de Linq son en realidad declarativas. Definen la consulta, pero no dicen ejecutarla. IEnumerable<T> no contiene datos, solo definición de consulta. Usted ha construido una consulta, está bien, ¿cómo obtener datos?

  • foreachIEnumerable. Dado que foreach es imprescindible, todos los datos deben recuperarse (consulta ejecutada).
  • ToList Call/ToDictionary. Esas colecciones almacenan datos reales por lo que para poblarlos el sistema tiene que ejecutar la consulta.
+0

Perfecto, lo entiendo ahora. Me estaba volviendo loco ... ¡gracias! – duckwizzle

2

LINQ se evalúa con pereza, de modo que no se ejecutará hasta que llame GetEnumerator y posiblemente incluso MoveNext.

trate de añadir un final de .ToList() a esa consulta y se debe ejecutar de inmediato.

+0

Sí, seguro que sí, ¡gracias! – duckwizzle

2

El IEqualityComparer no se llama hasta que el IEnumerable se enumera.

Trate

var new_texts = text_messages.Distinct(new SMSDupeRemover()).ToList(); 
+0

Oooh, no tenía ni idea. ¡Gracias! – duckwizzle

1

lo haría

List<MessageInfo> unique_msgs = 
    new List(text_messages.Distinct(new SMSDupeRemover())); 

para hacer inmediatamente la nueva lista. A menos que realmente necesite enumerador, para conservar la memoria.