检查对象是否更改的最佳做法是什么?

我需要知道如何检查对象是否已更改。 基本上我需要类似于名为TrackChanges的属性,当我将其设置为true一次并且如果此对象中的任何数据被“更改”时,同一对象(IsObjectChanged)上的方法可以返回true。

你有没有需要这样的东西,你是如何解决它的? 如果已经有这种情况的最佳实践,我不想发明轮子?

我想在我的setter中调用TrackChange = true之前克隆该对象。 当我调用IsObjectChanged()时,通过使用reflection,我将比较它的所有公共字段值和克隆的副本。 我不确定这是不是一个好方法。

有什么建议吗?

谢谢,burak ozdogan

当我需要跟踪对象的属性更改以进行测试时,我在对象PropertyChanged事件上挂钩了一个事件处理程序。 这对你有帮助吗? 然后,您的测试可以根据更改执行他们想要的任何操作。 通常我会计算更改次数,并将更改添加到词典等。

要实现此目的,您的类必须实现INotifyPropertyChanged接口。 然后任何人都可以附加和收听已更改的属性:

public class MyClass : INotifyPropertyChanged { ... } [TestFixture] public class MyTestClass { private readonly Dictionary _propertiesChanged = new Dictionary(); private int _eventCounter; [Test] public void SomeTest() { // First attach to the object var myObj = new MyClass(); myObj.PropertyChanged += SomeCustomEventHandler; myObj.DoSomething(); // And here you can check whether the object updated properties - and which - // dependent on what you do in SomeCustomEventHandler. // Eg that there are 2 changes - properties Id and Name changed once each: Assert.AreEqual(2, _eventCounter); Assert.AreEqual(1, _propertiesChanged["Id"]); Assert.AreEqual(1, _propertiesChanged["Name"]); } // In this example - counting total number of changes - and count pr property. // Do whatever suits you. private void SomeCustomEventHandler(object sender, System.ComponentModel.PropertyChangedEventArgs e) { var property = e.PropertyName; if (_propertiesChanged.ContainsKey(property)) _propertiesChanged[property]++; else _propertiesChanged[property] = 1; _eventCounter++; } } 

这有两个部分。 变更通知的事件是一个部分,但保持历史是另一个重要的部分。 entity framework也是这样做的(和LINQ to SQL一样),我也在自己的代码中实现了这一点。 至少,你为成员保留一个标志,表明它已经改变了。 根据您的要求,您也可以保留原始值。 这通常成为单独对象的任务。 entity framework将其更改跟踪保存在单独的对象中(如果我没记错的话,实体状态)。

在我自己的代码中,我开发了一个“DataMember”类,它不仅保存了值,还保留了更改标志,空状态和各种其他有用的东西。 这些DataMembers是Entity类中的私有成员,Entity提供了将数据公开为简单数据类型的属性。 属性get和set方法与DataMember交互以“做正确的事”,但DataMember确实改变了跟踪。 我的Entity类inheritance自“EntityBase”类,该类提供了在实体级别检查更改的方法,接受更改(重置更改标志)等。添加更改通知将是我接下来要做的事情,但是为个人提供DataMember类数据元素和拥有更改通知事件处理程序的EntityBase将简化这一过程。

编辑添加:

现在我正在工作,我可以添加一些代码示例。 这是我的DataMember类的接口定义:

 public interface IDataMember : IDataMember { T Value { get; set; } T Get(); void Set(T value); } public interface IDataMember { string FieldName { get; set; } string OracleName { get; set; } Type MemberType { get; } bool HasValue { get; set; } bool Changed { get; set; } bool NotNull { get; set; } bool PrimaryKey { get; set; } bool AutoIdentity { get; set; } EntityBase Entity { get; set;} object GetObjectValue(); void SetNull(); } 

这是实体类中的典型属性:

 private DataMember m_Monday; public bool? Monday { get { if (m_Monday.HasValue) return m_Monday.Get(); else return null; } set { if (value.HasValue) m_Monday.Set(value.Value); else m_Monday.SetNull(); } } 

请注意,DataMember可以支持属性为可空或不可以。

用于添加DataMember的构造函数代码:

  m_Monday = new DataMember("Monday"); Members.Add(m_Monday); 

布拉克

您可以查看entity framework或Microsoft的其他框架。 您可以看到PropertyChanging或PropertyChanged等事件。

看一下生成的代码。

您可能也会看一下NHibernate代码,但由于代码库非常庞大,因此最好查看Microsoft ORM生成器。

实现并使用INotifyPropertyChanged接口。 这里有一个很酷的方法,没有字符串文字。

为什么不创建List并将第一个对象放入,然后可以使用简单的比较将其与当前对象进行比较。

如上所述,您可以使用INotifyPropertyChanged查看对象中已更改的属性。

您应该创建一个事件并将其称为OnChanged而不是创建属性。