Тестирование объектов на предмет изменений - PullRequest
5 голосов
/ 26 марта 2010

У меня есть приложение, которое должно определить, внес ли пользователь изменения в объект.Итак, когда объект загружается впервые, я создаю глубокую копию (используя сериализацию / десериализацию) и сохраняю копию в отдельном поле.Копия становится myCurrentObject, а оригинал становится myOriginalObject.

Теперь мне нужно проверить myCurrentObject на изменения, которые я планирую сделать, сравнив его с myOriginalObject.Все, что мне нужно, это результат boolean, указывающий, были ли внесены какие-либо изменения.Я уже определил, что простое сравнение хеш-кода не будет работать.GetHashCode() генерирует разные результаты для двух объектов, даже когда нет изменений.

Я готовлюсь написать метод для сравнения свойств, но перед тем, как я это сделал, я подумал, чтопроверил бы, есть ли более простой и многократно используемый способ проверки myCurrentObject, чтобы увидеть, изменился ли он с myOriginalObject.

Есть предложения?Спасибо за вашу помощь.

Ответы [ 6 ]

5 голосов
/ 26 марта 2010

Вместо этого вы можете реализовать событие OnPropertyChanged для каждого из ваших свойств, тогда вы можете просто увидеть, было ли событие выброшено. Если вы специально внедрили INotifyPropertyChanged, вы получите дополнительное преимущество, заключающееся в том, что вы можете выполнять привязку WPF, если захотите.

Если это невозможно, вы, вероятно, могли бы реализовать решение с отражением, которое бы проходило через оба объекта в поисках различий.

2 голосов
/ 26 марта 2010
  1. Вы можете переопределить метод GetHashCode для соответствия вашим потребностям.
  2. Хеш-код может только сказать вам, что объект определенно изменился, он не может сказать, что объект определенно не изменился (потому что разные объекты могут возвращать один и тот же хеш-код).
  3. Исследуйте метод Object.Equals
2 голосов
/ 26 марта 2010

Что если событие возникает при изменении свойства?

http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.propertychanged.aspx

1 голос
/ 26 марта 2010

Вы можете добавить грязный флаг, который указывает, что любое поле изменилось. Установите грязный флаг в наборе свойств.

public bool IsDirty { get { return m_IsDirty; } }
public string Name {
    set
    {
        m_Name = value;
        m_IsDirty = true;
    }
}   
0 голосов
/ 26 марта 2010

Я бы рассмотрел использование абстрактного суперкласса, содержащего две вещи:

  • флаг, который объявляет, 'отслеживать' Изменения включены или нет (по умолчанию ложь)
  • словарь экземпляра который содержит историю значений ключа

... затем вызовите Base.TrackChange (string, object) в каждом методе доступа к свойствам, для которого вы хотите изменить. Где переданная строка является именем свойства (используйте отражение / извлечение имени свойства из трассировки стека: - означает, что код в каждом методе может быть точно таким же) ... а переданный объект - просто значение мета-переменной ». Некоторая тщательная проверка отражения / трассировки стека может означать, что вы можете удалить строковый параметр в этом методе ... означает, что вы соблюдаете минимальные требования к кодированию сущности класса C #.

Флаг есть, потому что инициализация основного состояния объекта означает, что изменения свойств (вызовы метода доступа) могут выполняться до тех пор, пока объект не будет полностью гидратирован в первый раз.

Словарь предназначен для включения изменений (одитинг?) И так далее. Уменьшите это значение до второго bool, если все, что вам нужно, это просто true / false в вопросе «IsDirty».

Что-то вроде:

public abstract Class EntityBase
{
    private bool _changesAreTracking = false;
    private Dictionary<string, object> _changes = null;
    public EntityBase() {}

    public TrackChange(string propertyName, object value)
    {
        if(_changesAreTracking)
        {
            if(_changes == null) { _changes = new Dictionary<string, object>(); }

            _changes.Add(propertyName, value);
        }
    }

    public void StartTrackChanges()
    {
        _changesAreTracking = true;
    }

    public bool HasChanged()
    {
        bool returnThis = false;

        if(_changes != null && _changes.Keys.Count() > 0)
        {
            returnThis = true;
        }

        return returnThis;
    }

    public bool HasChanged(string propertyName)
    {
        bool returnThis = false;

        if(_changes != null && _changes.Keys.Contains(propertyName))
        {
            returnThis = true;
        }

        return returnThis;
    }
}
0 голосов
/ 26 марта 2010

Обычно я делаю такой тест:

public string sodomizar(myObject object)
{
   return object.prop1.ToString() + object.prop2.ToString();
}

, затем тест:

if(sodomizar(object1)==sodomizar(object2))
{
doStuff();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...