C#最快速地了解对象中的某些内容已经发生了变化?

时间:2010-10-01 22:48:43

标签: c#

我想知道,如果任何私有或公共字段的值发生了变化。 除了覆盖GetHashCode()或计算CRC之外还有其他方法吗?

算法也应该很快。

-Thanks,

-Brajesh

4 个答案:

答案 0 :(得分:5)

通常,这将使用INotifyPropertyChanged接口(link)完成。实际上,将它与属性一起使用是非常实际的,而不是字段。但是,您可以为每个私有字段创建一个私有属性。将所有内容作为属性后,编辑setter以检查值是否已更改,然后调用NotifyPropertyChanged()(如果有)。

示例:

public event PropertyChangedEventHandler PropertyChanged;

private int _foo;

public int Foo
{
    get { return _foo; }
    set
    {
        if (_foo != value)
        {
            _foo = value;
            NotifyPropertyChanged("Foo");
        }
    }
}

private void NotifyPropertyChanged(string info)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}

答案 1 :(得分:2)

您可能希望在get / set访问器(a.k.a. properties)中封装所有数据(要监视更改)。

然后,在set accessor中,检查值是否已更改,将其设置为新值,然后:

  • 将_dirty设置为true(如果您需要稍后再检查)

  • 根据自己的喜好举办一些活动

关于CRC的一些注意事项 - 即使你的对象有非碰撞的CRC / HASH算法,你必须在某个地方有原始的哈希值。但是简单的哈希可能会重复,所以你再次遇到速度问题。

答案 2 :(得分:1)

如果它需要适用于任何类型并且需要检测任何修改,没有错误否定或误报,我没有看到比所有字段值的副本更好的方法以供参考。由于您需要快速,我建议如下:

  1. 编写一个使用反射执行所有字段值的浅表副本的例程。

  2. 编写一个按值比较字段的例程(如果您正在寻找嵌套结构中的更改,例如数组或集合,那么您的问题就更难了。)

  3. 完成上述工作后,您可以使用IL Emit编写一次执行Reflection的代码,并为浅拷贝和比较操作发出代码。现在,您可以使用一些DynamicMethod实例来执行每个操作。这些都非常快,一旦发射和发射。

答案 3 :(得分:1)

在每个公共setter中插入一个布尔值,如m_IsChanged,然后仅使用公共getter检查其中一个属性是否已更改。

示例:

private bool m_IsChanged = false;

private double m_DoubleValue;

//[...] all other private properties

public double DoubleValue
{
    get { return m_DoubleValue; }
    set
    {
       if(m_DoubleValue != value)
           m_IsChanged = true;

       m_DoubleValue = value;
    }
}

//[...] all other getters/setters

public bool IsChanged
{
   get { return m_IsChanged; }
}