2

My problem is ContainsKey is always returning false even when they key has been added and .Equals evaluates to true.

I have the following class:

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();
    }
}

I then have a dictionary that looks like this:

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

....

{
    // ALWAYS EVALUATES TO FALSE!
    if (_filteredStatisticsDict.ContainsKey(statisticsFilter) == false)
    {
         _filteredStatisticsDict.Add(statisticsFilter, new Statistics());
    }
}
Luke Belbina
  • 5,708
  • 12
  • 52
  • 75

2 Answers2

5

Unable to reproduce with the code you've given us.

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
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • You are correct. The issue was the StatisticsFilters were actually the same object and was to do with updating the reference etc. Very convoluted and confusing in our code. Thanks! – Luke Belbina May 25 '11 at 19:25
  • '@jon Skeet see a similar problem i have here http://stackoverflow.com/questions/27921694/how-to-implement-comparison-on-a-class-that-can-take-any-generic-type, please help. thanks. – Charles Okwuagwu Jan 13 '15 at 14:54
0

Are expecting the 'ToString()' to be the key? I think you will get the desired result by changing the Dictionary declaration to: Dictionary<string, Statistics>

// not always be false
if (_filteredStatisticsDict.ContainsKey(statistics.ToString() == false)
{
    _filteredStatisticsDict.Add(statisticsFilter.ToString(), newStatisitcs());
}

If I understand what you are trying to accomplish, this should work. With this method the dictionary key is based on the content of the filter.

Jim Reineri
  • 2,830
  • 3
  • 31
  • 32