Alex
Alex

Reputation: 307

Check if Dictionary contains key by comparing with different type

So what I want to do is this

var result = dictionary.ContainsKey(Guid.Empty);

Where dictionary is defined as var dictionary = new Dictionary<FooKeyClass, int>();

Right now FooKeyClass is basically just some data with a public property of type Guid. I have tried to override Equals, I've tried writing my own IComparer, I've tried to inherit IEquatable<Guid>. What ever I do I can't seem to get the desired functionality. Can someone please tell me if this even is possible in C# and if so how do I go by implementing it?

Here is the rest of the code, its kinda bloted with overrides as it is now though:

public class FooKeyClass : IEquatable<Guid>
{
    public Guid Guid { get; set; }
    public string Name { get; set; }

    public bool Equals(Guid guid)
    {
        if (guid == null)
            return false;
        return Guid.Equals(guid);
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        var p = obj as FooKeyClass;
        if ((object)p == null)
            return false;

        return p.Guid.Equals(this.Guid);
    }

    public static bool operator ==(FooKeyClass a, Guid b)
    {
        if (object.ReferenceEquals(a, b))
            return true;

        if (((object)a == null) || ((object)b == null))
            return false;

        return a.Guid.Equals(b);                
    }

    public static bool operator ==(FooKeyClass a, FooKeyClass b)
    {            
        if (System.Object.ReferenceEquals(a, b))
            return true;

        if (((object)a == null) || ((object)b == null))
            return false;

        return a.Guid.Equals(b.Guid);
    }

    public static bool operator !=(FooKeyClass a, FooKeyClass b)
    {
        return !(a == b);
    }

    public static bool operator !=(FooKeyClass a, Guid b)
    {
        return !(a == b);
    }

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

/// <summary>    
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var dictionary = new Dictionary<FooKeyClass, int>();

        var savedGuid = Guid.NewGuid();
        var tmpKey = new FooKeyClass() { Guid = savedGuid, Name = "feeefeee" };
        dictionary.Add(tmpKey, 42);

        var result = tmpKey.Equals(savedGuid); // no error
        result = tmpKey == savedGuid; // no error 

        result = dictionary.ContainsKey(savedGuid); // compile errror
        result = dictionary.Contains(savedGuid); // compile errror
        result = dictionary.Contains<Guid>(savedGuid); // compile errror

    }
}

Upvotes: 0

Views: 1517

Answers (1)

Sam Harwell
Sam Harwell

Reputation: 99889

Your two primary options are the following:

  1. Use the Guid to create an instance of FooKeyClass that you use as the actual key:

    var result = dictionary.ContainsKey(new FooKeyClass(Guid.Empty));
    
  2. Change the type of your dictionary to Dictionary<Guid, int>.

If you frequently use Guid.Empty as the key for some particular purpose, you can create the equivalent key FooKeyClass.Empty so you don't have to keep creating new instances of it.

Note that since your FooKeyClass is used as the key for a dictionary, you should make sure the result of your GetHashCode method cannot change after an instance is created. In your current implementation, if you set the FooKeyClass.Guid property after the key is added to a dictionary, the entry in the dictionary will be "lost" because the hash code changes. This situation is automatically avoided if you use Guid instead of FooKeyClass as the keys of your dictionary, or you can remove the setter for the FooKeyClass.Guid property and require the user to use a constructor instead.

Upvotes: 1

Related Questions