views:

978

answers:

3

I have this

 var n = ItemList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList();
 n.AddRange(OtherList.Select(s => new { s.Vchr, s.Id, s.Ctr, s.Vendor, s.Description, s.Invoice }).ToList(););

I would like to do this if it where allowed

n = n.Distinct((x, y) => x.Vchr == y.Vchr)).ToList();

I tried using the generic LambdaComparer but since im using anonymous types there is no type associate it with.

"Help me Obi Wan Kenobi, you're my only hope"

+7  A: 

The trick is to create a comparer that only works on inferred types. For intance

public class Comparer<T> : IComparer<T> {
  private Func<T,T,int> _func;
  public Comparer(Func<T,T,int> func) {
    _func = func;
  }
  public int Compare(T x,  T y ) {
    return _func(x,y);
  }
}

public static class Comparer {
  public static Comparer<T> Create<T>(Func<T,T,int> func){ 
    return new Comparer<T>(func);
  }
  public static Comparer<T> CreateComparerForElements<T>(this IEnumerable<T> enumerable, Func<T,T,int> func) {
    return new Comparer<T>(func);
  }
}

Now I can do the following ... hacky solution

var comp = n.CreateComparerForElements((x, y) => x.Vchr == y.Vchr);
JaredPar
Very slick. Im thinking though that in the interest of writing clean code I should create an interface to use as the T in an IEqualityComparer<T>.
kjgilla
I couldn't get by the problem. See below.
Tormod
A: 

Most of the time when you compare (for equality or sorting) you're interested in choosing the keys to compare by, not the equality or comparison method itself (this is the idea behind Python's list sort API).

There's an example key equality comparer here.

orip
A: 
        var list = new[]
                       {
                           new {Name = "John", Age = 20},
                           new {Name = "Frank", Age = 18},
                           new {Name = "Howard", Age = 20},
                           new {Name = "Bill", Age = 16},
                           new {Name = "Mike", Age = 20},
                       };
        var comparer = list.CreateComparerForElements((a, b) => a.Age.CompareTo(b.Age));

        var uniqueList = list.Distinct(comparer);

I can't get the above to work. Distinct still gets a squiggly requiring the type parameters to be specified "since they cannot be inferred", which I thought was the point.

Apologies for not posting this as a comment. It was too long.

Tormod