Как отличить две версии одного и того же объекта?
-
22-07-2019 - |
Вопрос
Я хочу сравнить два объекта разных версий и отобразить их различия в пользовательском интерфейсе.
Сначала я вызываю метод, чтобы узнать, есть ли разница между двумя объектами.
Метод:
public bool AreEqual(object object1,object object2, Type comparisionType)
Если вышеуказанный метод возвращает true, я вызываю метод GetDifferences
метод для получения различий, который:
public ObjectDifference[] GetObjectDifferences(object object1, object object2, Type comparisionType)
{
ArrayList memberList = new ArrayList();
ArrayList differences = new ArrayList();
memberList.AddRange(comparisionType.GetProperties());
memberList.AddRange(comparisionType.GetFields());
for (int loopCount = 0; loopCount < memberList.Count; loopCount++)
{
object objVal1 = null;
object objVal2 = null;
MemberInfo member = ((MemberInfo)memberList[loopCount]);
switch (((MemberInfo)memberList[loopCount]).MemberType)
{
case MemberTypes.Field:
objVal1 = object1 != null ? ((FieldInfo)memberList[loopCount]).GetValue(object1) : null;
objVal2 = object2 != null ? ((FieldInfo)memberList[loopCount]).GetValue(object2) : null;
break;
case MemberTypes.Property:
objVal1 = object1 != null ? ((PropertyInfo)memberList[loopCount]).GetValue(object1, null) : null;
objVal2 = object2 != null ? ((PropertyInfo)memberList[loopCount]).GetValue(object2, null) : null;
break;
default:
break;
}
if (AreValuesDifferentForNull(objVal1, objVal2))
{
ObjectDifference obj = new ObjectDifference(objVal1, objVal2, member, member.Name);
differences.Add(obj);
}
else if (AreValuesDifferentForPrimitives(objVal1, objVal2))
{
ObjectDifference obj = new ObjectDifference(objVal1, objVal2, member, member.Name);
differences.Add(obj);
}
else if (AreValuesDifferentForList(objVal1, objVal2))
{
ObjectDifference[] listDifference = GetListDifferences((ICollection)objVal1, (ICollection)objVal2, member);
differences.AddRange(listDifference);
}
else if ((!AreValuesEqual(objVal1, objVal2)) && (objVal1 != null || objVal2 != null))
{
ObjectDifference obj = new ObjectDifference(objVal1, objVal2, member, member.Name);
differences.Add(obj);
}
}
return (ObjectDifference[])differences.ToArray(typeof(ObjectDifference));
}
public class ObjectDifference
{
private readonly object objectValue1;
private readonly object objectValue2;
private readonly System.Reflection.MemberInfo member;
private readonly string description;
public object ObjectValue1
{
get { return objectValue1; }
}
public object ObjectValue2
{
get { return objectValue2; }
}
public System.Reflection.MemberInfo Member
{
get { return member; }
}
public string Description
{
get { return description; }
}
public ObjectDifference(object objVal1, object objVal2, System.Reflection.MemberInfo member, string description)
{
this.objectValue1 = objVal1;
this.objectValue2 = objVal2;
this.member = member;
this.description = description;
}
}
Для каждой разницы я создаю объект типа ObjectDifference и добавляю его в массив.Выделенная часть — это та, где я застрял!Если объект содержит другой сложный объект, моя программа дает мне различия, но я не знаю, к какому типу он принадлежал.
Например, у меня есть два объекта типа Имя.
class Name
{
string firstName, LastName;
List phNumber;
}
class PhoneNumber
{
string officeNo, MobileNo, HomeNo;
}
при сравнении двух объектов результат, который я получаю, прост:
firstname
- Джон МэриLastName
- Купер ЛорofficeNo
- 22222 44444MobileNo
- 989898 089089HomeNo
- 4242 43535
Иерархия, которая officeNo
имеет тип PhoneNumber
потеряно, что мне важно отобразить.
Как мне поддерживать этот тип дерева, создавая различия?Надеюсь, мне удастся объяснить мою проблему.
Решение
То, что вы пытаетесь сделать и отобразить, по своей сути сложно.Я делал это раньше (для процессов на основе диффграммы/дельты) и даже пытался отображать вложенные изменения в простом и дружелюбный путь непрост.
Если это соответствует вашей пользовательской базе, одним из вариантов может быть простая сериализация двух графиков в формате XML и использование чего-то вроде XML разница.