Home > Mobile >  Can I override Dictionary's Equals method?
Can I override Dictionary's Equals method?

Time:09-27

I want to override Dictionary's Equals method with return d1.Count == d2.Count && !d1.Except(d2).Any();

But I wanna do it for all the Dictionaries, and not just a specific type at a time. I currently have a public static bool IsEqualTo(this Dictionary<string, byte> d1, Dictionary<string, byte> d2) method in my ExtensionMethods class, but it's neither generic (working with any KeyValuePairs), neither does it actually override the default "Equals" method.

Is there any way I can do this, or am I stuck to using what I currently have (perhaps I could at least make it a bit more generic with a template)?

CodePudding user response:

To use your own custom ruls for Equality, you can implement IEqualityComparer<T> as CodeCaster suggested in the comments:

public sealed class DictionaryComparer<K, V> : IEqualityComparer<IDictionary<K, V>> {
  public bool Equals(IDictionary<K, V>? left, IDictionary<K, V>? right) {
    if (ReferenceEquals(left, right))
      return true;
    if (left is null || right is null)
      return false;

    return left.Count == right.Count && !left.Except(right).Any();
  }

  public int GetHashCode(IDictionary<K, V> value) => 
    value is null ? 0 : value.Count; 
}

Then whenever you want to compare two dictionaries:

Dictionary<int, string> dict1 = ...
Dictionary<int, string> dict2 = ...

if (new DictionaryComparer<int, string>().Equals(dict1, dict2)) {
  //TODO: relevant code here
}

You can implement an extension method if you like:

public static class DictionaryExtensions {
  public static bool EqualsToDictionary<K, V>(this IDictionary<K, V> left,
                                                   IDictionary<K, V> right) {
    var comparer = new DictionaryComparer<K, V>();

    return compare.Equals(left, right);
  }
}

then

Dictionary<int, string> dict1 = ...
Dictionary<int, string> dict2 = ...

if (dict1.EqualsToDictionary(dict2)) {
  //TODO: relevant code here
}

CodePudding user response:

Why not simply make make your IsEqualTo method generic?

public static bool IsEqualTo<K, V>(this IDictionary<K, V> d1, IDictionary<K, V> d2)
{
    return d1.Count == d2.Count && !d1.Except(d2).Any();
}

By extending IDictionary<TKey,TValue> instead of Dictionary<TKey,TValue> we can apply the extension method to other types of dictionaries like ConcurrentDictionary<TKey,TValue> or SortedDictionary<TKey,TValue> and many more.

Note that C# can infer the generic type parameters:

var d1 = new Dictionary<string, byte>();
var d2 = new Dictionary<string, byte>();
var s1 = new SortedDictionary<int, string>();
var s2 = new SortedDictionary<int, string>();

// Not necessary to specify the generic type parameters.
bool result1 = d1.IsEqualTo(d2);
bool result2 = s1.IsEqualTo(s2);
  • Related