Как различить две версии одного и того же объекта? - PullRequest
8 голосов
/ 13 марта 2009

Я хочу сравнить два объекта разных версий и отобразить их различия в пользовательском интерфейсе.

Сначала я вызываю метод, чтобы узнать, есть ли разница между двумя объектами

Метод:

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 и добавляю его в массив. Выделенная часть - та, где я застрял! Если объект содержит другой сложный объект, моя программа действительно дает мне различия, но я не знаю, к какому типу он принадлежал

Например, у меня есть два объекта типа Name

class Name
{
  string firstName, LastName;
  List phNumber;
}

class PhoneNumber
{
  string officeNo, MobileNo, HomeNo;
}

при сравнении двух объектов вывод, который я получаю, прост -

  • firstname - Джон Мэри
  • LastName - Купер Лор
  • officeNo - 22222 44444
  • MobileNo - 989898 089089
  • HomeNo - 4242 43535

Иерархия, которая officeNo относится к типу PhoneNumber, потеряна, что важно для отображения.

Как мне поддерживать этот тип дерева при создании различий? Надеюсь, я смогу понять мою проблему.

1 Ответ

6 голосов
/ 13 марта 2009

То, что вы пытаетесь сделать и показать, по своей сути сложно. Я делал это в прошлом (для процессов на основе диаграмм / дельта), и даже пытаться отобразить вложенных изменений простым и дружественным способом сложно.

Если это соответствует вашей пользовательской базе, одним из вариантов может быть просто сериализовать два графика в формате xml и использовать что-то вроде xml diff .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...