Джон Скит уже дал хорошее объяснение.
Однако, если все, что вам (или кому-либо еще, читающему этот вопрос), нужен эффективный метод сравнения словарей, это простое расширение на основе Linq, которое будет просточто:
/// <summary>
/// Compares two dictionaries for equality.
/// </summary>
/// <returns>
/// True if the dictionaries have equal contents or are both null, otherwise false.
/// </returns>
public static bool DictionaryEqual<TKey, TValue>(
this IDictionary<TKey, TValue> dict1, IDictionary<TKey, TValue> dict2,
IEqualityComparer<TValue> equalityComparer = null)
{
if (dict1 == dict2)
return true;
if (dict1 == null | dict2 == null)
return false;
if (dict1.Count != dict2.Count)
return false;
if (equalityComparer == null)
equalityComparer = EqualityComparer<TValue>.Default;
return dict1.All(kvp =>
{
TValue value2;
return dict2.TryGetValue(kvp.Key, out value2)
&& equalityComparer.Equals(kvp.Value, value2);
});
}
Возможно, это выглядит немного пушистым, но я хотел хорошей читабельности (и нулевых тестов).
Так что, если все, что вы хотите, это "одна строка" и вы уже знаете, что оба словаря не равны NULL и что тип TValue
корректно переопределяет метод Equals, тогда вам действительно нужно это очень много (без нулевых проверок, если TValue
, конечно, тип значения):
bool isEqual = dict1.Count == dict2.Count && dict1.All(kvp =>
{
TValue value2;
return dict2.TryGetValue(kvp.Key, out value2)
&& (kvp.Value == null ? value2 == null : kvp.Value.Equals(value2));
});
Если вы хотите выполнить сравнение, когда словари не должны иметь одинаковый тип значения, или если вы предпочитаете использовать делегат или лямбда-выражение вместочтобы реализовать IEqualityComparer, это расширение вместо этого поможет вам:
/// <summary>
/// Compares two dictionaries for equality using a custom value equality function.
/// </summary>
/// <returns>
/// True if both dictionaries are null or both have the same set of keys and comparing
/// their respective values for each key using the <paramref name="valueEqualityFunc"/>
/// returns true, otherwise false.
/// </returns>
public static bool DictionaryEqual<TKey, TValue1, TValue2>(
this IDictionary<TKey, TValue1> dict1, IDictionary<TKey, TValue2> dict2,
Func<TValue1, TValue2, bool> valueEqualityFunc)
{
if (valueEqualityFunc == null)
throw new ArgumentNullException("valueEqualityFunc");
if (dict1 == dict2)
return true;
if (dict1 == null | dict2 == null)
return false;
if (dict1.Count != dict2.Count)
return false;
return dict1.All(kvp =>
{
TValue2 value2;
return dict2.TryGetValue(kvp.Key, out value2)
&& valueEqualityFunc(kvp.Value, value2);
});
}
Как вы можете видеть, это почти то же самое, что и раньше.
Вот пример СШАпример ge:
var d1 = new Dictionary<string, string>();
var d2 = new Dictionary<string, string>();
d1.Add("key1", "dog");
d2.Add("key1", "Dog");
d1.Add("key2", "CAT");
d2.Add("key2", "cat");
bool isEqual = DictionaryEqual(d1, d2,
(s1, s2) => string.Equals(s1, s2, StringComparison.OrdinalIgnoreCase));
Если вы запустите приведенный выше код, isEqual
станет истинным.