1

Problem: Custom Object implements EqualityComparer and IEquatable, but Dictionary doesn't always use these methods.

Context: I have created a helper class, FilePath for dealing with file paths instead of treating them as strings. The helper class is responsible for determining if two file paths are equal. I then need to store FilePaths in a Dictionary<FilePath, object>.

Goal:

  Assert.True(new FilePath(@"c:\temp\file.txt").Equals(
      new FilePath(@"C:\TeMp\FIle.tXt")); 

  var dict = new Dictionary<FilePath, object>
  {
      {new FilePath(@"c:\temp\file.txt"), new object()}
  }

  Assert.True(dict.ContainsKey(new FilePath(@"c:\temp\file.txt"));

  Assert.True(dict.ContainsKey(new FilePath(@"C:\TeMp\FIle.tXt"));

I've created my FilePath class: public class FilePath : EqualityComparer, IEquatable { private string _fullPath;

    public FilePath (string fullPath)
    {
        _fullPath = Path.GetFullPath(fullPath);
    }

    public override bool Equals(FilePath x, FilePath y)
    {
        if (null == x || null == y)
            return false;

        return (x._fullPath.Equals(y._fullPath, StringComparison.InvariantCultureIgnoreCase));
    }

    public override int GetHashCode(FilePath obj)
    {
        return obj._fullPath.GetHashCode();
    }

    public bool Equals(FilePath other)
    {
        return Equals(this, other);
    }

    public override bool Equals(object obj)
    {
        return Equals(this, obj as FilePathSimple);
    }
}

Question:

Assert 1 and 2 pass, but Assert 3 fails:

 Assert.True(dict.ContainsKey(new FilePath(@"C:\TeMp\FIle.tXt"));
Philip Pittle
  • 11,821
  • 8
  • 59
  • 123

1 Answers1

2

I needed to override GetHashCode() as well:

 public override int GetHashCode()
 {
     return _fullPath.ToLower().GetHashCode();
 }

References: What's the role of GetHashCode in the IEqualityComparer<T> in .NET?

Compiler Warning (level 3) CS0659

Community
  • 1
  • 1
Philip Pittle
  • 11,821
  • 8
  • 59
  • 123
  • 1
    Although, its good that you managed to find your own solution to your question and post it for others.. I do wonder why you needed to ask it in the first place if your answer and question have almost the same time stamp.. – Sayse May 20 '14 at 10:32
  • 1
    Turned out to be a [Rubber Duck Question](http://blog.codinghorror.com/rubber-duck-problem-solving/). By detailing out exactly what the problem was, and experimenting along the way, I reached the solution by the time I was done writing the question. So I posted it anyway in case it helps someone down the line. – Philip Pittle May 20 '14 at 10:34