Search code examples
c#dictionarycontainskey

Dictionary ContainsKey does not seem to work with string[] key


I am trying to have a data structure with multiple string keys. To do this, I tried to create a Dictionary with string[] element. But the ContainsKey do no seem to work as I expect:

Dictionary<string[], int> aaa = new Dictionary<string[], int>();
int aaaCount = 0;
aaa.Add(new string[] { string1, string2 }, aaaCount++);

if (!aaa.ContainsKey(new string[] { string1, string2 }))
{
    aaa.Add(new string[] { string1, string2 }, aaaCount++);
}

I see that there are two entries in aaa after the execution of the code above while I was expecting only one. Is this the expected behaviour? How can I ensure that there are no duplicate entries in the Dictionary?

Note: I tried the same with a list as well (List and the result is the same - the Contains method does not really work with string[])


Solution

  • If you want to use string[] as TKey, you should pass IEqualityComparer<string[]> to the constructor of Dictionary. Because Otherwise Dictionary uses standard comparison for TKey and in case of string[] it just compares references hence string[] is reference type. You have to implement IEqualityComparer yourself. It can be done in the following way:

    (The implementation is quite naive, I provide it just as the starting point)

    public class StringArrayComparer : IEqualityComparer<string[]>
    {
        public bool Equals(string[] left, string[] right)
        {
            if (ReferenceEquals(left, right))
            {
                return true;
            }
    
            if ((left == null) || (right == null))
            {
                return false;
            }
    
            return left.SequenceEqual(right);
        }
    
        public int GetHashCode(string[] obj)
        {
            return obj.Aggregate(17, (res, item) => unchecked(res * 23 + item.GetHashCode()));
        }
    }