Comparer le contenu de deux objets pour l'égalité
J'ai deux complexes (i.e. les objets avec string, int, double, Liste et d'autres faits maison type de données) les objets du même type. Je voudrais comparer le contenu de deux d'entre eux pour s'assurer qu'ils sont identiques. Remarque: L'objet n'est pas mise en œuvre .Equals (je n'ai aucun contrôle sur ça) et ne pas mettre en œuvre IComparable.
Est-il un générique façon de réflexion (?) pour comparer le contenu de ces deux objets?
Merci!
Vous devez vous connecter pour publier un commentaire.
Eh bien oui, mais généralement connu sous le nom de l'interface IComparable.
Si vous pouviez descendre de la classe et de créer un enfant de mise en œuvre de IComparable, qui pourrait être idéal.
Equals
ouIEquatable<T>
, pasIComparable[<T>]
J'ai créé une classe pour effectuer une profonde comparer de .NET des Objets. Voir:
https://github.com/GregFinzer/Compare-Net-Objects
Ma solution de Travail.!
Espère que cela aide.!
Réflexion, mais le problème est le contenu de types - par exemple, vous ne pouvez pas utiliser
Equals
ouEqualityComparer<T>
, depuis le sous-données aussi ne sera pas facilement comparables si c'est unList<T>
etc.Combien de fois avez-vous besoin de faire cela? Pourriez-vous sérialiser et de comparer la valeur sérialisée? Qui pourrait être le plus robuste option.
GetHashcode fonctionne pour moi.
Je remplacer GetHashcode() dans chaque classe, avec tous les propriétés pertinentes X-OU-ed
par exemple,
Je itérer ce à travers toutes les classes, de nouveau X-OU les valeurs.
IsModified compare précédemment HashValue avec le courant.
Deux objets différents pourrait en effet de retourner le même HashValue, avec une chance de 1 à 4 milliards de dollars, mais pour de nombreuses fins, ce est assez bon pour moi.
Mais j'ai une bien meilleure idée, à l'aide d'un MemoryStream
ici est une Extension:
Je viens d'écrire ma version. Cette fonction de l'utilisation des génériques et de la réflexion. Il fonctionne par récursive de soi jusqu'à ce que toutes les choses dans l'objet déjà de comparer ou d'trouvé un qui n'est pas égal.
Sérialiser les objets à la chaîne XML et vous pouvez vous retrouver à faire une comparaison de chaîne entre les 2 objets qui sont sérialisés...
Pour mon dernier projet, j'ai fait une belle profondeur compair avec quelques fonctionnalités.
Il vous suffit d'écrire un utilitaire méthode d'une autre classe pour faire la comparaison. Cependant, c'est en supposant que les propriétés de la classe en question sont accessibles au public. Sont-ils?
Merci pour le MemoryStream approche, Marc. J'ai pensé sûr qu'il y a une erreur quand j'ai vu "ça" dans les arguments, mais, étonnamment, le compilateur fait vous permet de le faire de cette façon, hein? J'ai fait une légère modification et a choisi de substituer à est Égal à() à la place. Bravo également pour l'utilisation de la longueur et de la matrice de comparaison plutôt que SequenceEquals(). Prend une minute de plus à écrire, mais selon http://www.dotnetperls.com/sequenceequal, les performances sont bien meilleures.
La manière la plus rapide et la plus simple que j'ai trouvé est de sérialiser les deux objets à l'aide de MessagePack puis de comparer les tableaux d'octets.
Eh bien, vous pourriez écrire une logique de comparer tous les propriétés de ces deux objets les uns aux autres. Cela devient compliqué quand c'est un objet graphique complexe, avec des sous-types, de sorte que vous aurez besoin de déterminer quelle est assez bon.
Vous avez besoin d'une méthode de comparaison de quelque chose d'autre; en C++, vous pouvez simplement écrire une fonction globale, mais je ne pense pas que c# qui permet, tout comme Java ne fonctionne pas.
Ce que je voudrais faire est d'écrire une classe qui implémente iComparable, et a un ctor qui prend un objet de votre classe, et qui comprend votre est Égale à la fonction. Configurer de sorte que tous les il conserve est une référence à l'objet d'origine, pour sauver mallocations.
Ensuite, vous pouvez écrire
Foo(A).Equals(new Foo(B))
Vous pourriez hériter de la classe fournie, mais cela reviendrait à avoir besoin de créer et de suivre ces choses.