2012-11-14 134 views
-1

我有類:索引辭典列表<int>

public class Item 
{ 
    public List<int> val { get; set; } 
    public string info { get; set; } 
} 
public class IndexedDictionary : KeyedCollection<List<int>, Item> 
{ 
    protected override List<int> GetKeyForItem(Item item) 
    { 
     return item.val; 
    } 
} 

在 '主要()' 方法:

IndexedDictionary dic = new IndexedDictionary(); 
    dic.Add(new Item() { val = new List<int>() { 1, 2, 3 }, info = "Hello" }); 
    dic.Add(new Item() { val = new List<int>() { 1 }, info = "Bla.." }); 
    Console.WriteLine(dic[0].info); 
    Console.WriteLine(dic[new List<int>() { 1 }].info); 
    Console.ReadLine(); 

我得到錯誤行:

 Console.WriteLine(dic[new List<int>() { 1 }].info); 

你可以糾正我的代碼? Tks all

+0

請更具體一點關於你ecounter * *什麼錯誤... – Spontifixus

回答

1

在比較列表,你的詞典]比較實例(默認)不是序列。 對於回,下面的代碼將會給假

bool b = new List<int>() { 1 }.Equals(new List<int>() { 1 }) 

因此你應該實現IEqualityComparer。如下更改您的IndexedDictionary,它將工作。

public class IndexedDictionary : KeyedCollection<List<int>, Item> 
{ 
    public IndexedDictionary() : base(new MyEqualityComparer()) 
    { 
    } 

    protected override List<int> GetKeyForItem(Item item) 
    { 
     return item.val; 
    } 

    public class MyEqualityComparer : IEqualityComparer<List<int>> 
    { 
     public bool Equals(List<int> x, List<int> y) 
     { 
      return x.SequenceEqual(y); 
     } 

     public int GetHashCode(List<int> obj) 
     { 
      return obj.Aggregate(0, (s, x) => s ^= x.GetHashCode()); 
     } 
    } 
} 
+0

很好! :D非常感謝你 –

+1

儘管這個散列碼方法可行,但我會建議兩個更改。一,因爲它是散列獨立的秩序,這是不受歡迎的,如果順序很重要。我更喜歡'int temp = someprime; foreach(int in ...)temp =(temp + other)* someprime;'。另外,如果列表變大,則散列* all *項可能會成爲問題。考慮首先使用'Take(x)'來僅擁有前x個項目。只要X不是太小,稍高的衝突率就可能值得較低的哈希碼生成成本。 – Servy

2

您在此處犯的錯誤是假設List<int>的兩個實例相同,因爲它們包含相同的int。他們不是,他們是兩個完全不同的例子。

因此,您需要做的是將new List<int>() { 1 }分配給本地變量,並將該變量用作密鑰。

喜歡的東西:

var l1 = new List<int>() { 1 }; 
dic.Add(new Item() { val = l1, info = "Bla.." }); 
+0

列表是引用類型... –

+0

我知道,我有沒有指明其他? – CodingGorilla

0

由於您正在比較兩個不同的對象,所以失敗。使用List<int>作爲關鍵字沒什麼意義,因爲字典不會在意這些列表的內容。

例如:

var list1 = new List<int>() { 1, 2, 3 }; 
var list2 = new List<int>() { 1, 2, 3 }; 

Console.WriteLine("Equals: {0}", list1 == list2); 
Console.WriteLine("SequenceEquals: {0}", list1.SequenceEqual(list2)); 
Console.Read(); 

首先是假的,第二個是真實的。

有關更多信息,請參見該問題:Is there a built-in method to compare collections in C#?