Seleccionar distinto por dos propiedades en una lista

Tengo una list que contiene propiedades de tipo Guid y DateTime (así como otras propiedades). Me gustaría deshacerme de todos los elementos de esa lista donde Guid y DateTime son iguales (excepto uno). Habrá momentos en que esas dos propiedades serán las mismas que otros elementos en la lista, pero las otras propiedades serán diferentes, así que no puedo usar .Distinct()

 List messages = GetList(); //The list now contains many objects, it is ordered by the DateTime property messages = from p in messages.Distinct( what goes here? ); 

Esto es lo que tengo ahora, pero parece que debería haber una mejor manera

 List messages = GetList(); for(int i = 0; i < messages.Count() - 1) //use Messages.Count() -1 because the last one has nothing after it to compare to { if(messages[i].id == messages[i+1}.id && messages[i].date == message[i+1].date) { messages.RemoveAt(i+1); { else { i++ } } 

LINQ to Objects no proporciona esta funcionalidad fácilmente de una manera integrada, pero MoreLINQ tiene un práctico método DistinctBy :

 messages = messages.DistinctBy(m => new { m.id, m.date }).ToList(); 

DistinctBy Jon Skeet es definitivamente el camino a seguir, sin embargo, si está interesado en definir su propio método de extensión, puede que le apetezca en esta versión más concisa:

 public static IEnumerable DistinctBy (this IEnumerable source, Func keySelector) { var known = new HashSet(); return source.Where(element => known.Add(keySelector(element))); } 

que tiene la misma firma:

 messages = messages.DistinctBy(x => new { x.id, x.date }).ToList(); 

¿Qué hay de esto?

 var messages = messages .GroupBy(m => m.id) .GroupBy(m => m.date) .Select(m => m.First()); 

Puede consultar mi biblioteca PowerfulExtensions . Actualmente se encuentra en una etapa muy joven, pero ya puedes usar métodos como Distinct, Union, Intersect, excepto en cualquier cantidad de propiedades;

Así es como lo usas:

 using PowerfulExtensions.Linq; ... var distinct = myArray.Distinct(x => xA, x => xB); 

Prueba esto,

  var messages = (from g1 in messages.GroupBy(s => s.id) from g2 in g1.GroupBy(s => s.date) select g2.First()).ToList();