Dictionary.Equals () ha un'implementazione?
-
22-07-2019 - |
Domanda
Ho un dizionario che sto confrontando con un altro dizionario (variabili digitate come IDictionary). Facendo d1.Equals (d2) si ottiene falso. Scrivere il mio codice qui sotto produce true. Entrambi sono System.Collections.Generic.Dictionary
. Mi sto perdendo qualcosa o Dictionary
non ha un'implementazione Equals
che confronta chiavi / valori?
private static bool DictEquals<K, V>(IDictionary<K, V> d1, IDictionary<K, V> d2)
{
if (d1.Count != d2.Count)
return false;
foreach (KeyValuePair<K, V> pair in d1)
{
if (!d2.ContainsKey(pair.Key))
return false;
if (!Equals(d2[pair.Key], pair.Value))
return false;
}
return true;
}
Soluzione
Dictionary.Equals () utilizza i uguali predefiniti da Object, verificando se i due oggetti sono lo stesso riferimento, così come tutte le altre raccolte predefinite. Sei libero di creare la tua sottoclasse con semantica di valore, anche se in genere ciò include anche l'immutabilità delle cose.
Altri suggerimenti
Probabilmente il metodo Equals
della classe Dictionary
ricorre semplicemente all'implementazione predefinita ereditata da Object
, cioè confronta semplicemente il riferimento oggetto <=> passato con il proprio riferimento. Vedi qui: Riferimento Object.Equals
Supponendo che due dizionari, uno essendo SortedList<TKey, TValue>
e uno Dictionary<TKey, TValue>
, siano confrontati per uguaglianza, dovrebbe davvero tornare vero se gli elementi sono uguali? Sarebbe piuttosto male, dal momento che hanno caratteristiche e caratteristiche diverse (il SortedList<,>
ad esempio consente il recupero tramite indice).
Inoltre, l'uguaglianza e il codice hash sono logicamente collegati tra loro. Il codice hash dovrebbe essere immutabile, altrimenti tutti gli algoritmi basati su hash non funzioneranno. Non puoi garantirlo quando stai usando i contenuti per verificare l'uguaglianza. Pertanto, l'implementazione predefinita (verificando che si tratti della stessa istanza) è piuttosto sana. Tuttavia, sei libero di creare il tuo confronto sull'uguaglianza dei contenuti.
Altri hanno menzionato che sta usando l'implementazione Object.Equals, è possibile utilizzare quanto segue per sovrascriverlo:
public class EqualsDictionary<T, T> : Dictionary<T, T>
{
public override bool Equals(object obj)
{
//Place your comparison implementation here
}
}
I riferimenti in .NET possono essere usati per incapsulare l'identità di un oggetto, aspetti mutabili del suo stato, entrambi o nessuno dei due, oltre a incapsulare aspetti immutabili dello stato di un oggetto. In generale, in assenza di un motivo particolare per supporre il contrario, .NET presuppone che i riferimenti a oggetti mutabili vengano utilizzati allo scopo di incapsulare l'identità. Suppone inoltre che nei casi in cui il codice paragona i riferimenti senza sapere cosa rappresentino, è meglio sbagliare sul lato della segnalazione di cose disuguali. Come tale, due riferimenti ad oggetti mutabili sono generalmente considerati equivalenti se e solo se identificano lo stesso oggetto, e i tipi mutabili sono così scoraggiati dal scavalcare Equals
per indicare qualcos'altro. Al contrario, il codice che utilizza riferimenti per incapsulare lo stato mutabile dovrebbe usare mezzi diversi da Object.Equals()
per confrontarli.