【问题标题】:C# Dictionary ContainsKeyC# 字典 ContainsKey
【发布时间】:2011-05-25 19:05:06
【问题描述】:

我的问题是 ContainsKey 始终返回 false,即使它们已添加密钥并且 .Equals 的计算结果为 true。

我有以下课程:

public class StatisticsFilter 
{
    private String someString1;
    private String someString2;
    .....

    public override string ToString()
    {
        return string.Format("{0}-{1}-{2}-{3}-{4}", someString1, someString2, ...)
    }

    public override bool Equals(object obj)
    {            
        return obj.ToString().Equals(ToString());
    }

    public override int GetHashCode()
    {
        return ToString().GetHashCode();
    }
}

然后我有一个看起来像这样的字典:

private readonly IDictionary<StatisticsFilter, Statistics> _filteredStatisticsDict =
            new Dictionary<StatisticsFilter, Statistics>();

....

{
    // ALWAYS EVALUATES TO FALSE!
    if (_filteredStatisticsDict.ContainsKey(statisticsFilter) == false)
    {
         _filteredStatisticsDict.Add(statisticsFilter, new Statistics());
    }
}

【问题讨论】:

  • 那么问题肯定出在你的GetHashCode上。它是否总是为同一个实例返回相同的值?
  • 你传递的是key还是类的实例?
  • 等等,ContainsKey(statisticsFilter) 评估为 false,还是 ContainsKey(statisticsFilter) == false 评估为 false?

标签: c# dictionary equality containskey


【解决方案1】:

无法使用您提供给我们的代码进行重现。

using System;
using System.Collections.Generic;

public class StatisticsFilter 
{
    private String someString1;
    private String someString2;

    public StatisticsFilter(string x, string y)
    {
        this.someString1 = x;
        this.someString2 = y;
    }

    public override string ToString()
    {
        return string.Format("{0}-{1}xyz", someString1, someString2);
    }

    public override bool Equals(object obj)
    {            
        return obj.ToString().Equals(ToString());
    }

    public override int GetHashCode()
    {
        return ToString().GetHashCode();
    }
}

class Test
{
    static void Main()
    {
        var dict = new Dictionary<StatisticsFilter, int>();

        var sf1 = new StatisticsFilter("hello", "there");
        var sf2 = new StatisticsFilter("hello", "there");

        dict[sf1] = 10;
        Console.WriteLine(dict.ContainsKey(sf2)); // Prints true
    }
}

【讨论】:

  • 你是对的。问题是 StatisticsFilters 实际上是同一个对象,并且与更新引用等有关。在我们的代码中非常复杂和混乱。谢谢!
  • '@jon Skeet 看到我在这里遇到的类似问题stackoverflow.com/questions/27921694/…,请帮忙。谢谢。
【解决方案2】:

期待“ToString()”是关键吗?我认为您将通过将 Dictionary 声明更改为:Dictionary&lt;string, Statistics&gt;

来获得所需的结果
// not always be false
if (_filteredStatisticsDict.ContainsKey(statistics.ToString() == false)
{
    _filteredStatisticsDict.Add(statisticsFilter.ToString(), newStatisitcs());
}

如果我了解您要完成的工作,这应该可以。 使用此方法,字典键基于过滤器的内容。

【讨论】:

  • 是的,这会起作用,但它实际上并不是字典的可读性那么差。
猜你喜欢
  • 1970-01-01
  • 2012-04-19
  • 2016-08-25
  • 1970-01-01
  • 2011-08-26
  • 2012-03-12
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
相关资源
最近更新 更多