繁体   English   中英

C#:按列表索引的字典

[英]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>EqualsGetHashCode方法不考虑列表的内容。 如果要将对象集合用作键,则需要实现自己的集合类型,该类型将覆盖Equals ,以便检查集合中对象的相等性(也许使用Enumerable.SequenceEqual 。)

Dictionary类使用引用比较来查找指定的键,这就是为什么即使列表包含相同项,它们也不同的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM