Je veux obtenir les noms de toutes les propriétés qui ont changé pour faire correspondre des objets. strong> J'ai ces classes (simplifiées): à la fin je souhaite avoir une liste de Le différence code> s comme celui-ci: p> < Pré> xxx pré>
modifiéProperty code> doit contenir le nom des propriétés modifiées. p> p>
5 Réponses :
Je le fais en utilisant ceci:
//This structure represents the comparison of one member of an object to the corresponding member of another object. public struct MemberComparison { public static PropertyInfo NullProperty = null; //used for ROOT properties - i dont know their name only that they are changed public readonly MemberInfo Member; //Which member this Comparison compares public readonly object Value1, Value2;//The values of each object's respective member public MemberComparison(PropertyInfo member, object value1, object value2) { Member = member; Value1 = value1; Value2 = value2; } public override string ToString() { return Member.name+ ": " + Value1.ToString() + (Value1.Equals(Value2) ? " == " : " != ") + Value2.ToString(); } } //This method can be used to get a list of MemberComparison values that represent the fields and/or properties that differ between the two objects. public static List<MemberComparison> ReflectiveCompare<T>(T x, T y) { List<MemberComparison> list = new List<MemberComparison>();//The list to be returned if (x.GetType().IsArray) { Array xArray = x as Array; Array yArray = y as Array; if (xArray.Length != yArray.Length) list.Add(new MemberComparison(MemberComparison.NullProperty, "array", "array")); else { for (int i = 0; i < xArray.Length; i++) { var compare = ReflectiveCompare(xArray.GetValue(i), yArray.GetValue(i)); if (compare.Count > 0) list.AddRange(compare); } } } else { foreach (PropertyInfo m in x.GetType().GetProperties()) //Only look at fields and properties. //This could be changed to include methods, but you'd have to get values to pass to the methods you want to compare if (!m.PropertyType.IsArray && (m.PropertyType == typeof(String) || m.PropertyType == typeof(double) || m.PropertyType == typeof(int) || m.PropertyType == typeof(uint) || m.PropertyType == typeof(float))) { var xValue = m.GetValue(x, null); var yValue = m.GetValue(y, null); if (!object.Equals(yValue, xValue))//Add a new comparison to the list if the value of the member defined on 'x' isn't equal to the value of the member defined on 'y'. list.Add(new MemberComparison(m, yValue, xValue)); } else if (m.PropertyType.IsArray) { Array xArray = m.GetValue(x, null) as Array; Array yArray = m.GetValue(y, null) as Array; if (xArray.Length != yArray.Length) list.Add(new MemberComparison(m, "array", "array")); else { for (int i = 0; i < xArray.Length; i++) { var compare = ReflectiveCompare(xArray.GetValue(i), yArray.GetValue(i)); if (compare.Count > 0) list.AddRange(compare); } } } else if (m.PropertyType.IsClass) { var xValue = m.GetValue(x, null); var yValue = m.GetValue(y, null); if ((xValue == null || yValue == null) && !(yValue == null && xValue == null)) list.Add(new MemberComparison(m, xValue, yValue)); else if (!(xValue == null || yValue == null)) { var compare = ReflectiveCompare(m.GetValue(x, null), m.GetValue(y, null)); if (compare.Count > 0) list.AddRange(compare); } } } return list; }
Je reçois un Nombre de paramètres Mismatch i> Exception lorsque j'utilise cela.
Nous commençons par 2 méthodes simples: areequal compare simplement les versions sérialisées de deux objets à l'aide de JSON.NET, cela le permet de traiter les types de référence et les types de valeur différemment. P > GetDifefence vérifie les propriétés sur les objets transmis et les compare individuellement. P> Pour obtenir une liste de différences: p> var oldPersonList = new List<Person> {
new Person { Name = "Bill" },
new Person { Name = "Bob" }
};
var newPersonList = new List<Person> {
new Person { Name = "Bill" },
new Person { Name = "Bobby" }
};
var diffList = oldPersonList.Zip(newPersonList, GetDifference)
.Where(d => d.ChangedProperties.Any())
.ToList();
Ici, vous avez un code qui fait ce que vous voulez avec réflexion code>.
J'ai passé tout en œuvre en essayant d'écrire une solution de réflexion plus rapide à l'aide de délégués dactylographiés. Mais éventuellement, j'ai abandonné et éventé à Marc Gravell's bibliothèque membre rapide pour atteindre des performances plus élevées qu'avec la réflexion normale.
Code: strong> P> PropertyComparer pc = new PropertyComparer();
var diffs = PropertyComparer.GetDifferences(pc, oldPersonList, newPersonList).ToList();
Tout le monde essaie toujours de se fier et d'écrire ces moyens trop génériques d'extraction de données. Il y a un coût à cela.
Pourquoi ne pas être vieille école simple. P>
avoir une fonction de fonction membre getDifferrences. P>
virtual List<String> GetDifferences(Person otherPerson){ var diffs = new List<string>(); if(this.X != otherPerson.X) diffs.add("X"); .... }
Cela fonctionnera. Mais cela ne prendra pas 10 minutes. Mes cours sont beaucoup plus complexes que l'exemple que j'ai donné. Il faudra au moins une journée, avec des lignes de code HunDrets et des erreurs éventuelles dans ce code.
Assurez-vous de peser la perf. Si un faible nombre de comparaisons, la route de réflexion est bien. Si vous courez cela plus de centaines de milliers +, je serais plus méfiant.
Faire cela pour les listes est une douleur réelle i> (supposant que vous devez manipuler ajouter / supprimer / re-commande / etc.); Cependant, sur une base d'objet, veuillez consulter: Stackoverflow.com/questions/3060382/... - qui fait exactement ce
@Marcgravell: Je l'ai essayé et cela renvoie les attributs qui sont des listes comme Delta. Merci quand même.
Vous souciez-vous des propriétés qui ne sont pas dans les deux objets, c'est-à-dire La matriculation est-elle considérée comme une modification lorsque vous comparez une personne à un étudiant?
Je correspond aux personnes avec la propriété
nom code>, puis la comparez si une correspondance est trouvée. Donc, seuls les objets du même type peuvent être comparés.
Depuis que les sujets sont une liste, si 1 professeur dispose de 2 éléments de sujet de la liste et d'autres professeurs a par exemple seulement 1 ou 3, cet élément supplémentaire ou moins sujet aurait la différence?