ma classe:
public class myClass
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public int D { get; set; }
}
et exemple principal:
Dictionary<myClass, List<string>> dict = new Dictionary<myClass, List<string>>();
myClass first = new myClass();
first.A = 2;
first.B = 3;
myClass second = new myClass();
second.A = 2;
second.B = 3;
second.C = 5;
second.D = 6;
dict.Add(first, new List<string>());
if (dict.ContainsKey(second))
{
//
//should come here and update List<string> for first (and only in this example) key
//
}
else
{
//
//if myFirst object has difference vlues of A or B properties
//
dict.Add(second, new List<string>());
}
Comment faire ça?
Si vous voulez toujours que le dictionnaire ne compare que sur A et B, vous avez deux options. Soit tilisez le constructeur qui implémente IEqualityComparer<TKey>
et y mettre votre logique de comparaison, ou faire implémenter votre classe GetHashCode and Equals pour que le comparateur par défaut vous donne les résultats que vous recherchez.IEquateable<T>
Si vous voulez seulement comparer sur A et B dans votre situation, vous devrez utiliser la propriété .Keys et la méthode d'extension Linq Contains qui vous permet de passer un IEqualityComparer<T>
. Cependant, lorsque vous le faites de cette façon, vous perdez les avantages de la vitesse d'utilisation d'un dictionnaire, alors utilisez-le avec parcimonie.
public class MyClassSpecialComparer : IEqualityComparer<myClass>
{
public bool Equals (myClass x, myClass y)
{
return x.A == y.A && x.B == y.B
}
public int GetHashCode(myClass x)
{
return x.A.GetHashCode() + x.B.GetHashCode();
}
}
//Special case for when you only want it to compare this one time
//NOTE: This will be much slower than a normal lookup.
var myClassSpecialComparer = new MyClassSpecialComparer();
Dictionary<myClass, List<string>> dict = new Dictionary<myClass, List<string>>();
//(Snip)
if (dict.Keys.Contains(second, myClassSpecialComparer ))
{
//
//should come here and update List<string> for first (and only in this example) key
//
}
//If you want it to always compare
Dictionary<myClass, List<string>> dict = new Dictionary<myClass, List<string>>(new MyClassSpecialComparer());
Par défaut, la comparaison place les objets dans des compartiments en fonction de leur code de hachage. Une comparaison détaillée est ensuite effectuée (en appelant Equals
) si deux codes de hachage sont identiques. Si votre classe ne fournit ni GetHashCode
ni n'implémente l'égalité, la valeur par défaut object.GetHashCode
sera utilisé - auquel cas rien de spécifique à votre classe ne sera utilisé pour la sémantique de comparaison de valeurs. Seule la même référence sera trouvée. Si vous ne le souhaitez pas, implémentez GetHashCode
et implémentez l'égalité.
Par exemple:
public class myClass
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public int D { get; set; }
public bool Equals(myClass other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return other.A == A && other.B == B && other.C == C && other.D == D;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof (myClass)) return false;
return Equals((myClass) obj);
}
public override int GetHashCode()
{
unchecked
{
int result = A;
result = (result*397) ^ B;
result = (result*397) ^ C;
result = (result*397) ^ D;
return result;
}
}
}
Remplacez votre myClass:
Méthode GetHashCode
Méthode égale
Pour implémenter la méthode GetHashCode, vous pouvez simplement XOR GetHashCodes à partir de vos propriétés entières.
Substituez éventuellement la méthode ToString et implémentez l'interface IEquatable