Adam Adam - 1 month ago 12
C# Question

c# Dictionary<object, T> lookup value

Not sure how to best phrase this which is probably why I'm having difficulty looking it up. Here is a sample console application to demonstrate my meaning.

class Program
{
static void Main(string[] args)
{
var item1 = new Item("Number");
var item2 = new Item("Number");

var dict = new Dictionary<Item, string>();
dict.Add(item1, "Value");
Console.WriteLine(dict.ContainsKey(item2));

var dict2 = new Dictionary<string, string>();
dict2.Add("Number", "Value");
Console.WriteLine(dict2.ContainsKey("Number"));
Console.Read();
}

class Item
{
readonly string number;
public Item(string number)
{
this.number = number;
}
}
}


In this example
dict.ContainsKey(item2)
returns
false
and
dict2.ContainsKey("Number")
returns
true
. Can Item be defined in such a way that it would behave like a string? The best I can come up with is

static void Main(string[] args)
{
var item1 = new Item("Number");
var item2 = new Item("Number");

var dict = new Dictionary<string, string>();
dict.Add(item1.ToString(), "Test");
Console.WriteLine(dict.ContainsKey(item2.ToString()));
Console.Read();
}

class Item
{
readonly string number;

public Item(string number)
{
this.number = number;
}

public override string ToString()
{
return number;
}
}


This example is contrived, Item would have more fields and ToString() would joint them all up.

Answer

You need to override Equals and GetHashCode. Dictionary use Equals and GetHashCode method to compare keys for equality.

class Item
{
    readonly string number;
    public Item(string number)
    {
        this.number = number;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Item);
    }

    public override int GetHashCode()
    {
        // this is c# 6 feature 
        return number?.GetHashCode() ?? 0;

        // If you are not using c# 6, you can use
        // return number == null ? 0 : number.GetHashCode();
    }

    private bool Equals(Item another)
    {
        if (another == null)
            return false;

        return number == another.number;
    }
}

If you have more than one field, you need to account all fields in the Equals and GetHashCode method.

Comments