0

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

    }
}
Alex
  • 197
  • 1
  • 11
  • This seems like an awful lot of overhead, not to mention it seems to be the wrong approach. If you were to go to all this effort, wouldn't it simply be easier to wrap the dictionary in a custom dictionary class of your own making and expose a different ContainsKey method that does what you are looking for? As is, you are masking intent. It does NOT Contain the key at all, it just may contain an object that contains your key. I'd recommend attacking the problem from a different angle. – David L Sep 15 '14 at 15:56
  • Ye, you're probably right. Just my stubbornness overcoming my rational thinking while coding late in the afternoon. Wrapping dictionary in a custom dictionary with the additional desired functionality sounds like a more sane approach. Thanks! – Alex Sep 16 '14 at 06:47

1 Answers1

1

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.

Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • The Guid of an object should never change, that is my intention at least and the Guid will never be empty. Thats only in theory though and what I'm striving for. – Alex Sep 16 '14 at 06:50
  • I supposed that `Dictionary>` also is a plausible solution. – Alex Sep 16 '14 at 06:53