Using Distinct with LINQ and Objects

后端 未结 5 1415
余生分开走
余生分开走 2021-01-03 23:20

Until recently, I was using a Distinct in LINQ to select a distinct category (an enum) from a table. This was working fine.

I now need to have it distinct on a class

5条回答
  •  失恋的感觉
    2021-01-03 23:38

    For explanation, take a look at other answers. I'm just providing one way to handle this issue.

    You might like this:

    public class LambdaComparer:IEqualityComparer{
      private readonly Func _comparer;
      private readonly Func _hash;
      public LambdaComparer(Func comparer):
        this(comparer,o=>0) {}
      public LambdaComparer(Func comparer,Func hash){
        if(comparer==null) throw new ArgumentNullException("comparer");
        if(hash==null) throw new ArgumentNullException("hash");
        _comparer=comparer;
        _hash=hash;
      }
      public bool Equals(T x,T y){
        return _comparer(x,y);
      }
      public int GetHashCode(T obj){
        return _hash(obj);
      }
    }
    

    Usage:

    public void Foo{
      public string Fizz{get;set;}
      public BarEnum Bar{get;set;}
    }
    
    public enum BarEnum {One,Two,Three}
    
    var lst=new List();
    lst.Distinct(new LambdaComparer(
      (x1,x2)=>x1.Fizz==x2.Fizz&&
               x1.Bar==x2.Bar));
    

    You can even wrap it around to avoid writing noisy new LambdaComparer(...) thing:

    public static class EnumerableExtensions{
     public static IEnumerable SmartDistinct
      (this IEnumerable lst, Func pred){
       return lst.Distinct(new LambdaComparer(pred));
     }
    }
    

    Usage:

    lst.SmartDistinct((x1,x2)=>x1.Fizz==x2.Fizz&&x1.Bar==x2.Bar);
    

    NB: works reliably only for Linq2Objects

提交回复
热议问题