2017-01-05 5 views
3

날짜 비교에 허용 오차가있는 IEqualityComparer을 구현하려고합니다. 나는 또한 this question을 들여다 보았다. 문제는 LINQ .GroupJoin()IEqualityComparer을 사용하고 있기 때문에 해결 방법을 사용할 수 없다는 것입니다. 나는 관용을 허용하는 몇 가지 구현을 시도했다. 두 개체가 있기 때문에 Equals()을 얻을 수는 있지만 구현 방법을 알아낼 수는 없습니다 GetHashCode(). 이 일이 모두/모든 개체를 추가 적용허용 오차가있는 IEqualityComparer GetHashCode 사용

public class ThingWithDateComparer : IEqualityComparer<IThingWithDate> 
{ 
    private readonly int _daysToAdd; 

    public ThingWithDateComparer(int daysToAdd) 
    { 
     _daysToAdd = daysToAdd; 
    } 

    public int GetHashCode(IThingWithDate obj) 
    { 
     unchecked 
     { 
      var hash = 17; 
      hash = hash * 23 + obj.BirthDate.AddDays(_daysToAdd).GetHashCode(); 
      return hash; 
     } 
    } 

    public bool Equals(IThingWithDate x, IThingWithDate y) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public interface IThingWithDate 
{ 
    DateTime BirthDate { get; set; } 
} 

GetHashCode() 밖으로 HashTable를 구축 .GroupJoin()으로 :

내 최고의 시도는 다음과 같이 보인다. 이것은 작동하지 않습니다.

+0

daysTo는 1 일의 공차 내에서 1 월 5 일과 1 월 6 일과 같이 공차를 추가합니까? 이 평등의 정의는 전이 적이 지 않으므로 모든 객체에 대해 동일한 해시 코드를 반환한다는 간단한 해결책 외의 IEqualityComparer를 사용하여 올바르게 구현할 수 있을지는 의문입니다. –

+0

잊어 버려. 'GroupJoin'을'SelectMany'와 간단한'Where'로 대체하십시오 (별로 좋지는 않지만 작동해야합니다). –

+0

@mikez 네, 그건 공차입니다. 이름이 잘못되었습니다. 이 작업을 할 수 없다면'GroupJoin()'의 커스텀 버젼을 구현할 것입니다. –

답변

2

문제는 개념적으로 불가능합니다. 작업을 수행하려고하는 작업에 필요한 평등의 형식이 아닌 방식으로 개체를 비교하려고합니다. 예를 들어, GroupJoin은 A가 B와 같고 B가 C와 같으면 A가 C와 같지만 실제로는 그렇지 않다는 가정에 따라 달라집니다. A와 B는 그룹으로 묶을 수 있도록 함께 "가까이"있을 수 있지만 A와 C는 그룹에 포함되지 않을 수 있습니다.

IEqualityComparer을 구현하지 않아도됩니다. 필요한 계약을 이행 할 수 없기 때문입니다. 하나의 컬렉션에있는 아이템을 다른 컬렉션에있는 "충분히 가깝다"는 모든 아이템에 매핑하고자한다면, 당신은 그 알고리즘을 스스로 작성해야 할 것입니다 (그렇게 효율적으로하면 어렵습니다. 그러나 비효율적으로 수행하는 것은 GroupJoin을 사용하는 것보다 그 작업을 수행 할 수 없기 때문에 어렵지 않아야합니다.

+0

이것은 정답 인 것 같습니다. 그 대답은 대답이 없다는 것이 실망 스럽습니다. –

1

주어진 기준에 맞는 논리 해시 코드를 생성 할 수있는 방법이 없습니다.
해시 코드는 2 개의 날짜가 서로 연결되어야하는지 확인하는 데 사용됩니다. 그룹화해야한다면 동일한 해시 코드를 반환해야합니다.

"float"이 5 일이면 1/1/2000은 1/4/2000과 동일한 해시 코드를 생성해야하고 1/4/2000은 1/8/2000과 동일한 해시 코드를 생성해야 함을 의미합니다. 2000 년 (그들은 서로 5 일 이내이기 때문에). 이는 2000 년 1 월 1 일에 a = b 및 b = c 인 경우 a = c이므로 2000 년 1/8과 동일한 코드를 가짐을 의미합니다.

1/1/2000 및 1/8/2000은 5 일간의 "float"밖에 있습니다.

+0

매우 사실입니다. 'GroupJoin'의 사용을 폐지하고 왼쪽에서 시드가있는 'Comparer'을 허용하는 버전을 구현해야한다고 생각합니다. –