C# 测试对象的更改

C# 测试对象的更改,c#,comparison,C#,Comparison,我有一个应用程序需要确定用户是否对对象进行了更改。因此,当第一次加载对象时,我创建了一个深度副本(使用序列化/反序列化),并将副本保存到一个单独的字段中。副本变为myCurrentObject,原件变为myOriginalObject 现在我需要测试myCurrentObject是否有变化,我计划通过将其与myOriginalObject进行比较来实现这一点。我所需要的只是一个布尔值结果,指示是否进行了任何更改。我已经确定一个简单的hashcode比较是行不通的GetHashCode()为两个对

我有一个应用程序需要确定用户是否对对象进行了更改。因此,当第一次加载对象时,我创建了一个深度副本(使用序列化/反序列化),并将副本保存到一个单独的字段中。副本变为
myCurrentObject
,原件变为
myOriginalObject

现在我需要测试
myCurrentObject
是否有变化,我计划通过将其与
myOriginalObject
进行比较来实现这一点。我所需要的只是一个
布尔值
结果,指示是否进行了任何更改。我已经确定一个简单的hashcode比较是行不通的
GetHashCode()
为两个对象生成不同的结果,即使没有更改

我正准备编写一个方法来逐个属性进行比较,但在编写之前,我想检查一下是否有一种更简单、更可重用的方法来测试
myCurrentObject
,看看它是否已从
myOriginalObject
更改


有什么建议吗?感谢您的帮助。

如果在属性更改时引发事件,该怎么办


相反,您是否可以在每个属性上实现OnPropertyChanged事件,然后您就可以查看事件是否被抛出。如果您专门实现INotifyPropertyChanged,您将获得额外的好处,如果您愿意,可以进行WPF绑定


如果这是不可能的,您可能会实现一个反射解决方案,该解决方案将遍历两个对象以查找差异。

您可以添加一个脏标志,指示任何字段都已更改。在属性集中设置脏标志

public bool IsDirty { get { return m_IsDirty; } }
public string Name {
    set
    {
        m_Name = value;
        m_IsDirty = true;
    }
}   

我通常这样做测试:

public string sodomizar(myObject object)
{
   return object.prop1.ToString() + object.prop2.ToString();
}
然后测试:

if(sodomizar(object1)==sodomizar(object2))
{
doStuff();
}
  • 您可以重写GetHashCode方法以反映您的需要
  • 散列代码只能告诉您一个对象已被确定更改,而不能告诉您一个对象未被确定更改(因为不同的对象可以返回相同的散列代码)
  • 一定要研究一下这个方法

  • 我会考虑使用包含两个事物的抽象超类:

    • 声明是否“跟踪”的标志 “更改”是否启用(默认为 (错误)
    • 词典实例 包含键控值历史记录的
    。。。然后在您感兴趣的每个属性访问器中调用Base.TrackChange(字符串、对象)。其中传递的字符串是属性的名称(使用反射/从堆栈跟踪中提取属性名称:-表示每个方法中的代码可以完全相同)。。。传递的对象只是元变量“value”。仔细检查反射/堆栈跟踪可能意味着您可以删除此方法上的字符串参数。。。意味着您将实体C类编码要求降至最低

    该标志存在是因为对象的基本状态初始化意味着在对象第一次完全水合之前,可以进行属性更改(设置访问器调用)

    字典是用来追踪变化的(审计?)等等。如果你所需要的只是简单的“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;
        }
    }
    
    公共抽象类EntityBase
    {
    私有bool_changesAreTracking=false;
    专用字典_changes=null;
    公共EntityBase(){}
    公共轨迹更改(字符串属性名称,对象值)
    {
    如果(_changesRetracking)
    {
    如果(_changes==null){u changes=new Dictionary();}
    _添加(propertyName,value);
    }
    }
    public void StartTrackChanges()
    {
    _changesAreTracking=true;
    }
    公共布尔值已更改()
    {
    bool returnThis=false;
    if(_changes!=null&&u changes.Keys.Count()>0)
    {
    returnThis=true;
    }
    归还这个;
    }
    公共布尔值已更改(字符串属性名称)
    {
    bool returnThis=false;
    if(_changes!=null&&u changes.Keys.Contains(propertyName))
    {
    returnThis=true;
    }
    归还这个;
    }
    }
    
    这绝对可以+从我这里得到1。