Тестирование объектов для изменений

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

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

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

Какие-либо предложения?Спасибо за помощь.

5
задан David Veeneman 26 March 2010 в 15:34
поделиться

6 ответов

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

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

2
ответ дан 13 December 2019 в 22:05
поделиться

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

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

5
ответ дан 13 December 2019 в 22:05
поделиться
  1. Вы можете переопределить метод GetHashCode, чтобы отразить твои нужды.
  2. Хэш-код может только сказать вам, что объект определенно изменился, он не может сказать вам, что объект определенно не изменился (потому что разные объекты могут возвращать один и тот же хеш-код).
  3. Изучите метод Object.Equals
2
ответ дан 13 December 2019 в 22:05
поделиться

Обычно я провожу такие проверки, например:

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

затем проверяю:

if(sodomizar(object1)==sodomizar(object2))
{
doStuff();
}
0
ответ дан 13 December 2019 в 22:05
поделиться

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

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

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

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

Словарь существует для того, чтобы дать возможность отслеживать изменения (аудит?) И так далее. Если все, что вам нужно, это просто true / false в вопросе IsDirty, уменьшите масштаб до второго bool.

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

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
ответ дан 13 December 2019 в 22:05
поделиться

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

public bool IsDirty { get { return m_IsDirty; } }
public string Name {
    set
    {
        m_Name = value;
        m_IsDirty = true;
    }
}   
1
ответ дан 13 December 2019 в 22:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: