0

我是一名业余程序员,这似乎是一个很容易解决的问题,但我就是不知道如何解决。下面是 C# 代码,它的行为不像我想要的那样。我希望这会返回 3,但会抛出KeyNotFoundException. 列表是相同的,所以它不应该返回 3 吗?谢谢你的帮助。

Dictionary<object, double> dict = new Dictionary<object, double>();
dict.Add(new List<object>() { "a", "b" }, 3);
double output = dict[new List<object>() { "a", "b" }];
4

3 回答 3

8

List<T>是没有特殊Equals实现的引用类型。因此,在您的情况下,虽然您的两个列表实例具有相同的内容,但它们仍然是不同的实例,因此在键查找时不被视为相等。

根据您的需要,您可以使用不同的解决方案:

  1. 如果列表中的项目数量始终相同,则可以使用元组:

    Dictionary<Tuple<string, string>, double> dict =
        new Dictionary<Tuple<string, string>, double>();
    dict.Add(Tuple.Create("a", "b"), 3);
    double output = dict[Tuple.Create("a", "b")];
    
  2. 如果项目数量不同,您可以创建自己的列表来比较其内容。

于 2013-07-18T13:56:04.497 回答
1

两个列表都是单独的实例,因此ReferenceEquals返回false,但默认情况下使用。您可以IEqualityComparer<IList<object>>为字典构造函数实现自定义:

public class ListComparer : IEqualityComparer<IList<object>>
{
    public bool Equals(IList<object> x, IList<object> y)
    {
        if (x == null || y == null) return false;
        return x.SequenceEqual(y);
    }

    public int GetHashCode(IList<object> list)
    {
        if (list == null) return int.MinValue;
        int hash = 19;
        unchecked // Overflow is fine, just wrap
        {
            foreach (object obj in list)
                if(obj != null)
                    hash = hash + obj.GetHashCode();
        }
        return hash;
    }
}

现在它按预期工作:

var  dict = new Dictionary<List<object>, double>(new ListComparer());
dict.Add(new List<object>() { "a", "b" }, 3);
double output = dict[new List<object>() { "a", "b" }]; // 3.0
于 2013-07-18T14:01:41.290 回答
1

因为有两个不同的对象/实例。

于 2013-07-18T13:56:52.900 回答