2009-08-19 5 views
1

Except() 메서드로 문제가 있습니다. 차이를 반환하는 대신 원래 집합을 반환합니다.IEnumerable.Except() 및 사용자 지정 비교 자

저는 Account 클래스에서 IEquatable 및 IEqualityComparer를 구현하려고 시도했습니다. 또한 Account에 대해 별도의 IEqualityComparer 클래스를 만들려고했습니다.

Except() 메서드가 main에서 호출 될 때 내 사용자 지정 Equals() 메서드를 호출하는 것처럼 보이지 않지만 Count()를 시도하면 사용자 지정 GetHashCode() 메서드가 호출되었습니다!

저는 어딘가에서 사소한 실수를 저질렀습니다. 나는 신선한 쌍둥이가 나를 도울 수 있기를 바랍니다.

주 :

IEnumerable<Account> everyPartnerID = 
    from partner in dataContext.Partners 
    select new Account { IDPartner = partner.ID, Name = partner.Name }; 


IEnumerable<Account> hasAccountPartnerID = 
    from partner in dataContext.Partners 
    from account in dataContext.Accounts 
    where 
     !partner.ID.Equals(Guid.Empty) && 
     account.IDPartner.Equals(partner.ID) && 
     account.Username.Equals("Special") 
    select new Account { IDPartner = partner.ID, Name = partner.Name }; 

IEnumerable<Account> noAccountPartnerID = 
    everyPartnerID.Except(
     hasAccountPartnerID, 
     new LambdaComparer<Account>((x, y) => x.IDPartner.Equals(y.IDPartner))); 

계정 :

public class Account : IEquatable<Account> 
    { 
     public Guid IDPartner{ get; set; } 
     public string Name{ get; set; } 

/*  #region IEquatable<Account> Members 

     public bool Equals(Account other) 
     { 
      return this.IDPartner.Equals(other.IDPartner); 
     } 

     #endregion*/ 
    } 

LambdaComparer : 당신은 단지 하나의 함수에 전달할 때이를 사용하기 때문에

public class LambdaComparer<T> : IEqualityComparer<T> 
    { 
     private readonly Func<T, T, bool> _lambdaComparer; 
     private readonly Func<T, int> _lambdaHash; 

     public LambdaComparer(Func<T, T, bool> lambdaComparer) : 
      this(lambdaComparer, o => o.GetHashCode()) 
     { 
     } 

     public LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash) 
     { 
      if (lambdaComparer == null) 
       throw new ArgumentNullException("lambdaComparer"); 
      if (lambdaHash == null) 
       throw new ArgumentNullException("lambdaHash"); 

      _lambdaComparer = lambdaComparer; 
      _lambdaHash = lambdaHash; 
     } 

     public bool Equals(T x, T y) 
     { 
      return _lambdaComparer(x, y); 
     } 

     public int GetHashCode(T obj) 
     { 
      return _lambdaHash(obj); 
     } 
    } 

답변

6

기본적으로 당신의 LambdaComparer 클래스, 고장 "ID 해시 코드"공급자. 다른 것을 제공하지 않는 경우. 해시 코드는 Except에 의해 사용되며 이는 문제의 원인입니다. 여기

세 가지 옵션 :

  1. 자신의 ExceptBy 메소드를 구현하고 바람직하게는 그런 종류의 물건을 포함하는 MoreLINQ에 기여한다.

  2. IEqualityComparer<T>의 다른 구현을 사용하십시오. 나는 에서 사용할 수있는 ProjectionEqualityComparer 클래스를 가지고 있습니다. 코드 as posted in another question을 사용할 수 있습니다. 당신은 신속하게에만 평등 매개 변수를 다음과 같이 공급 될 때 작동하도록 LambdaComparer을 고칠 수

    new LambdaComparer<Account>((x, y) => x.IDPartner.Equals(y.IDPartner)), 
              x => x.IDPartner.GetHashCode()); 
    
1

:

  • 해시를 위해 사용하도록 LambdaComparer 코드로 람다 식을 전달

    public LambdaComparer(Func<T, T, bool> lambdaComparer) : 
         this(lambdaComparer, o => 1) 
        { 
        }