2016-07-11 19 views
2

我嘗試使用下面的代碼的對象列表轉換成詞典:轉換鮮明的列表詞典不工作

var MyDictionary = MyList.Distinct().ToDictionary(i => i.ObjectId, i => i); 

我知道,字典不應該包含重複的元素,因此.Distinct() 。但是,如果存在重複元素,我仍然會收到以下異常:

具有相同密鑰的項目已添加。

MyList是myObject的名單,看起來像這樣:

public class MyObject{ 

     public string ObjectId { get; set; } 

     public string FName { get; set; } 

     public string LName { get; set; } 

    } 

是否有更好的方法來創建對象列表的字典嗎?或者我做錯了什麼?

+6

我猜你想按'ObjectId'而不是調用'Distinct'。要麼你有多個對同一個對象的多個引用,要麼有多個具有相同「ObjectId」的對象。 –

+1

即僅僅因爲你的MyObject不等於(.Distinct)並不意味着它們的ObjectIds不相等。 – RJFalconer

+0

@DStanley哪種解決方案更高效?使用groupBy或自定義比較器與Distinct()? –

回答

4

如果您想在ObjectId上進行比較,您需要將自定義比較器傳遞至.Distinct()。你可以這樣做是這樣的:

class MyObjectComparer : IEqualityComparer<MyObject> 
{ 
    public bool Equals(MyObject x, MyObject y) 
    { 
     return x.ObjectId == y.ObjectId; 
    } 

    public int GetHashCode(MyObject obj) 
    { 
     return obj.ObjectId.GetHashCode(); 
    } 
} 

var MyDictionary = MyList 
    .Distinct(new MyObjectComparer()) 
    .ToDictionary(i => i.ObjectId, i => i); 
+2

您還需要正確實施'GeHashCode'。 –

+0

@DStanley哎呀,你說得對。固定。 – itsme86

1

默認情況下,使用EqualsGetHashCode方法中內置對象的默認工作,但您的字典僅對id有效。您需要將IEqualityComparer中的IEqualityComparer轉換爲不同的值,以便比較Id以測試項目是否相等或使MyObject暗示EqualsGetHashCode並在Id上進行比較。

3

您可以通過使用組,然後從列表中選擇如下第一:

var MyDictionary = MyList.GroupBy(i => i.ObjectId, i => i).ToDictionary(i => i.Key, i => i.First()); 
+1

你不需要'i => i'參數作爲'GroupBy',只需要一個lambda就可以默認。 – juharr

+0

是的,這是真的,它不需要,但我寫了它,以防萬一,如果用戶想要選擇一個特定的變量,而不是整個對象。因此,他們可以使用Group by中的第二個參數來選擇特定變量或完整對象,例如: ** MyList.GroupBy(i => i.ObjectId,i =>(i.FName + i.LName))** –