LINQ

2010-02-17 2 views
11

와 사용자 정의 유형으로 그룹 I는 다음과 같이 정의되는 좌표와이 클래스LINQ

public class Item 
{ 
     public Coordinate coordinate { get; set; } 
     ... 
     ... 
} 

이 방법 :

public class Coordinate 
{ 
     public Coordinate(float latitude, float longitude) 
     { 
      Latitude = latitude; 
      Longitude = longitude; 
     } 

     public float Latitude { get; private set; } 
     public float Longitude { get; private set; } 
} 

을 그리고 난 그런 LINQ 쿼리 갖고 싶어 :

0 :

As mentioned here by MSDN

var grouped = from it in items 
       group it by it.Coordinate into grp 
       select grp; 
나는 내 좌표 클래스 같음 무시한다면 이것이 가능하다고 생각

쿼리 변수를 다른 메소드에 전달해야하는 경우 명명 된 유형을 사용하십시오. 키에 대해 자동 구현 된 속성을 사용하여 특수 클래스를 만든 다음 Equals 및 GetHashCode 메서드를 재정의합니다. 구조체를 사용할 수도 있습니다.이 경우 은 정확히 메서드를 재정의해야합니다. 이 자동 구현 속성

클래스 좌표에 대한

구현 같음 것을 불변의 클래스를 구현 : 자세한 내용은 방법 참조 여전히

public override bool Equals(object obj) 
{ 
     var coord = obj as Coordinate; 
     if(coord == null) return false; 
     return (Latitude == coord.Latitude && Longitude == coord.Longitude); 
} 

을 나는 비슷한 좌표로 그룹 내 LINQ 쿼리를 얻을 질수 내 테스트를 실패로하여 보여줍니다에 과부하가

[TestMethod] 
public void GroupBy_3ItemsWith2DifferentCoordinates_Returns2Groups() 
{ 
    var items = new List<Item> 
     { 
      new Item {Coordinate = new Coordinate(10, 10)}, 
      new Item {Coordinate = new Coordinate(10, 10)}, 
      new Item {Coordinate = new Coordinate(12, 10)}, 
     }; 
    var grouped = from it in items 
        group it by it.Coordinate into g 
        select g; 
    Assert.AreEqual(2, grouped.Count()); 
} 

매개 변수로 IEqualityComparer를 사용하지만 GrouBy 메서드는 group 절을 사용하는 동일한 방법이 있습니까? 내가 뭔가 잘못하고있는거야 ?? 이견있는 사람?

답변

22

당신은 Equals 구현을 보여 주었지만 GetHashCode는 보여주지 않았습니다. 그룹화가 작동하려면 둘 다 (그리고 일관된 방식으로) 대체해야합니다.

예제를 GetHashCode 구현 : 정확한 어떤지 float 값을 비교하는 것은 다소 위험이 항상 있다는

public override int GetHashCode() 
{ 
    int hash = 23; 
    hash = hash * 31 + Latitude.GetHashCode(); 
    hash = hash * 31 + Longitude.GetHashCode(); 
    return hash; 
} 

주 - 그러나 나는 적어도 그들이 어떤 계산을 수행하지 않는 것을 주어, 단위 테스트가 통과 기대 . 매개 변수로 IEqualityComparer 걸리는 GrouBy 방법에 과부하가 발생하지만, 그룹 USING 절 등가가

+0

그냥 시도를, 그 무엇의 I 실종되었다.감사합니다 :) public override int GetHashCode ( ) { return ((int) Latitude * 100)^((int) Longitude * 100); } –

+0

이것이 해시 코드에서 수행중인 작업 인 경우 동등한 코드가 일치하는지 확인해야합니다. 서로 일치해야합니다. –

+0

Latitude.GetHashCode()^Longitude.GetHashCode()는 위도와 경도를 반전 할 때도 동일한 결과를 제공합니다. 그래서 그것은 좋은 해결책이 아니 었습니다. 나는 coord (x, y)! = coord (y, x); 작업 순서가 중요하기 때문에 코드가 작동합니다. 정밀도 덕분에 도움이되었습니다 :) –

2

?

당신이 그냥 빨리 인라인 솔루션을 원하고 키에 대한 정확한 유형 타격에 대해 걱정하지 않을 경우 당신은 항상 익명의 유형별로 그룹이 있습니다 :

var grouped = 
    from it in items 
    group it by new {it.Coordinate.Latitude, it.Coordinate.Longitude}; 
+0

그 해결책을 알았지 만 좌표 클래스를 키로 사용하지 않고 익명 유형으로 만 사용할 수 있습니다. –