Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple IEqualityComparer<T> question

Tags:

c#

I'm trying to remove duplicate entries from a list which contains a generic object.

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

And the code to remove the dupes:

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

The problem is Equals and GetHashCode is never called. Anyone have any idea why?

like image 297
duck Avatar asked May 12 '11 16:05

duck


3 Answers

Because Distinct is lazy. Try to add ToList() at the end.

Longer answer. Linq operations are actually declarative ones. They define query, but they do not tell to execute it. IEnumerable<T> doesn't contain data, just query definition. You have constructed query, okay, how to get data?

  • foreach the IEnumerable. Since foreach is imperative all data must be retrieved (query executed).
  • Call ToList/ToDictionary. Those collections store real data so in order to populate them system has to execute query.
like image 97
Andrey Avatar answered Sep 21 '22 14:09

Andrey


LINQ is lazily evaluated, so that won't execute until you call GetEnumerator and possibly even MoveNext.

Try adding a .ToList() to the end of that query and it should execute right away.

like image 26
Cory Nelson Avatar answered Sep 18 '22 14:09

Cory Nelson


The IEqualityComparer isn't called until the IEnumerable is enumerated.

Try

var new_texts = text_messages.Distinct(new SMSDupeRemover()).ToList();
like image 29
foson Avatar answered Sep 18 '22 14:09

foson