2013-01-21 97 views
2

我有這樣的對象:組複雜類型的值

notes:[ 
    { user: { 
      name: "A", 
      group:{ 
       id:1, 
       name:"Group 1" 
      } 
    }, 
    { user: { 
      name: "B", 
      group:{ 
       id:1, 
       name:"Group 1" 
      } 
    }] 

,我需要通過羣組它..所以我嘗試這樣做:

​​

但我因爲分組的問題不工作(我認爲這是因爲它使用引用來分組複雜類型)。 如果我將n.User.Group更改爲n.User.GroupId它有效,但如果我這樣做,我無法獲取組名稱。

+1

這歸結爲如何'Group'定義平等,特別是通過'INT的GetHashCode()','布爾等於(對象) ',和(最好)'bool IEquatable .Equals(Group)'。 –

回答

3

您需要覆蓋Group類中的Equals和GetHashCode。 R#爲其生成此類代碼:

public class Group 
{ 
    public int GroupId { get; set; } 
    public string Name { get; set; } 

    protected bool Equals(Group other) 
    { 
     return GroupId == other.GroupId; 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != this.GetType()) return false; 
     return Equals((Group) obj); 
    } 

    public override int GetHashCode() 
    { 
     return GroupId; 
    } 
} 
+0

注意:基於對象生命期間可變的事物的平等可能是非常危險的。如果「GroupId」被更改,數據可能變得不可理解(在字典中等)。但是:對於'GroupBy'的確定性生命週期,它應該沒問題。 –

+0

我猜Group是這裏的一個實體。所以GroupId不應該真的改變(或者它也會導致很多其他問題)。 – pkmiec

3

是的,這是正確的。默認情況下,類都是唯一的,但是你可以重寫唯一性。

  1. 組對象上覆蓋Equals(object obj) & GetHasCode()實現自己的平等
  2. 實施IEqualityComparer<Group>並通過以此爲第三個參數的方法的GroupBy。
+2

「複雜類型都是唯一的」有點誤導:適用於*類*,是:但結構默認爲按字段相等(儘管次優,注意:如果使用相等性測試,總是會覆蓋它更好) –

+0

謝謝爲了指出這一點。我更新了我的答案以反映這一點。 –

1

您有幾種選擇在這裏:

  • 確保類組對象實現GetHashCode和equals。實現這些可能非常簡單,比如根據ID比較組
  • Group中的ID,並獲得組名中的第一個用戶組的組名。所有分組的用戶都屬於同一個組,因此名稱將相同
  • 如果您無權訪問組類的源,請使用一個包裝器進行分組,該包裝器根據組的標識實現GetHashCode和Equals包裝。
0

你拿佔據了優勢比較匿名類的寫,因爲

notes.GroupBy(n => new{n.User.Group.ID,n.User.Group.Name});