[英]C#: Dictionary indexed by List
我嘗試編寫一個程序,其中Dictionary由List索引。 (相信我,我願意,是的,有選擇,但是我喜歡按列表編制索引)。 有一個最小的工作(實際上不工作,只有最后一行是一個問題)示例:
using System;
using System.Collections.Generic;
namespace test
{
class Program
{
static void Main(string[] args)
{
Dictionary<List<String>, int> h = new Dictionary<List<string>,int>();
List<String> w = new List<string> {"a"};
h.Add(w, 1);
w = new List<string>{"b"};
h.Add(w,2);
w = new List<string>{"a"};
int value = 0;
h.TryGetValue(w, out value);
Console.WriteLine(value+" "+h[w]);
}
}
如果有人調試該程序,他將清楚地看到h中有兩個元素,但是仍然無法通過正確的索引--- h [w]訪問這些元素。 我是錯了還是發生了什么奇怪的事情?
您的應用程序的問題源於以下事實:
new List<String> { "a" } != new List<String> { "a" }
列表是否相等將檢查兩個引用是否引用同一實例。 在這種情況下,他們沒有。 相反,您創建了兩個具有相同元素的列表...這並不使它們相等。
您可以通過創建自定義的“平等比較器”來解決此問題:
public class ListEqualityComparer<T> : IEqualityComparer<List<T>>
{
public bool Equals(List<T> list1, List<T> list2)
{
return list1.SequenceEquals(list2);
}
public int GetHashCode(List<T> list)
{
if(list != null && list.Length > 0)
{
var hashcode = list[0].GetHashCode();
for(var i = 1; i <= list.Length; i++)
hashcode ^= list[i].GetHashCode();
return hashcode;
}
return 0;
}
}
然后將其傳遞給Dictionary構造函數:
Dictionary<List<String>, int> h =
new Dictionary<List<string>,int>(new ListEqualityComparer<String>());
問題是按列表進行索引,您要按的索引不是列表中的數據,但實際上您是通過指向該列表的內存指針(即此列表所在的內存地址)進行索引的。
您在一個內存位置創建了一個列表,然后在另一個內存位置(即,創建新實例時)創建了一個完全不同的列表。 這兩個列表即使包含相同的數據也有所不同,這意味着您可以向詞典中添加任意數量的列表。
一種解決方案是,不是按列表編制索引,而是按字符串編制索引,並使用逗號分隔的包含您列表中所有數據的List作為索引。
這將永遠無法為您服務,因為List<T>
的Equals
和GetHashCode
方法不考慮列表的內容。 如果要將對象集合用作鍵,則需要實現自己的集合類型,該類型將覆蓋Equals
,以便檢查集合中對象的相等性(也許使用Enumerable.SequenceEqual
。)
Dictionary類使用引用比較來查找指定的鍵,這就是為什么即使列表包含相同項,它們也不同的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.