У меня есть приложение, которое должно определить, внес ли пользователь изменение в объект. Так, когда объект сначала загружается, я создаю глубокую копию (использующий сериализацию/десериализацию) и сохраняю копию к отдельному полю. Копия становится myCurrentObject
, и оригинал становится myOriginalObject
.
Теперь я должен протестировать myCurrentObject
для изменений, которые я планирую сделать путем сравнения его с myOriginalObject
. Все, в чем я нуждаюсь, является a boolean
результат, указывающий, были ли какие-либо изменения внесены. Я уже решил, что простое сравнение хэш-кода не будет работать. GetHashCode()
генерирует различные результаты для двух объектов, даже когда нет никаких изменений.
Я готовлюсь писать метод, чтобы сделать сравнение свойства свойством, но прежде чем я сделаю, я думал, что проверю, чтобы видеть, существует ли более простое и больше допускающего повторное использование способа протестировать myCurrentObject
видеть, изменилось ли это от myOriginalObject
.
Какие-либо предложения?Спасибо за помощь.
Что делать, если событие возникает при изменении свойства?
Вместо этого вы могли бы реализовать событие OnPropertyChanged для каждого из ваших свойств, тогда вы могли бы просто увидеть, было ли событие когда-либо сгенерировано. Если вы специально реализуете INotifyPropertyChanged, вы получите дополнительное преимущество, заключающееся в том, что вы можете выполнять привязку WPF, если захотите.
Если это невозможно, вы, вероятно, могли бы реализовать решение с отражением, которое будет обходить оба объекта в поисках различий.
Обычно я провожу такие проверки, например:
public string sodomizar(myObject object)
{
return object.prop1.ToString() + object.prop2.ToString();
}
затем проверяю:
if(sodomizar(object1)==sodomizar(object2))
{
doStuff();
}
Я бы подумал об использовании абстрактного суперкласса, содержащего две вещи:
... затем вызовите 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;
}
}
Вы можете добавить грязный флаг, указывающий, что любое поле было изменено. Установите грязный флаг в наборе свойств.
public bool IsDirty { get { return m_IsDirty; } }
public string Name {
set
{
m_Name = value;
m_IsDirty = true;
}
}