If I have a Dictionary<int[], int>
, which contains 2 entries
{1, 2, 3} , 1 and
{4, 5, 6} , 2
How do I check whether the dictionary contains the key {1, 2, 3}
? If i do:
if (dictionary.ContainsKey(new int[] {1,2,3})
{
// do things
}
It will not return the correct result as the created array is different from the key array. I know you can override the Equals method for a custom class, but is there another way to check if a dictionary which has an array as the key, contains an entry whose key array has the same values within it as the comparison array?
Well, arrays are compared by reference so we have
int[] a = new int[] {1, 2, 3};
int[] b = new int[] {1, 2, 3}; // same content, different reference
// Prints "No"
Console.WriteLine(a.Equals(b) ? "Yes" : "No");
Dictionary<int[], string> dict = new Dictionary<int[], string>() {{
a, "Some Value"}};
// Prints "Not Found"
Console.WriteLine(dict.TryGetValue(b, out var value) ? value : "Not Found");
So we have to explain .Net how to compare arrays; we can do it with a comparer:
public class SequenceEqualityComparer<T> : IEqualityComparer<IEnumerable<T>> {
public bool Equals(IEnumerable<T> x, IEnumerable<T> y) {
if (ReferenceEquals(x, y))
return true;
else if (null == x || null == y)
return false;
return Enumerable.SequenceEqual(x, y, EqualityComparer<T>.Default);
}
public int GetHashCode(IEnumerable<T> obj) =>
obj == null ? 0 : obj.FirstOrDefault()?.GetHashCode() ?? 0;
}
And we should declare the dictionary while mentioning the comparer:
Dictionary<int[], string> dict =
new Dictionary<int[], string>(new SequenceEqualityComparer<int>()) {
{a, "Some Value"}};
Now we can do business as usual:
// Returns "Some Value"
Console.WriteLine(dict[b]);