.net 对对象进行脏检查?

.net 对对象进行脏检查?,.net,.net,考虑以下对象: Public Class Foo dim m_SomePropertyInFoo as string public property SomePropertyInFoo as string get return m_SomePropertyInFoo end get set(value as string) m_SomePropertyInFoo = value end set end Class

考虑以下对象:

Public Class Foo
   dim m_SomePropertyInFoo as string

    public property SomePropertyInFoo as string
    get
        return m_SomePropertyInFoo
    end get
    set(value as string)
        m_SomePropertyInFoo = value
    end set
end Class
我想确定
SomePropertyInFoo
何时有一个新值,该值将
Foo
的实例限定为dirty。这里有一个陷阱:我不想在每个setter中调用一些函数,因为我不希望开发人员每次都必须实现代码(因为他们可能会犯错误并丢失属性)

这里有一个陷阱:我不想在每个setter中调用一些函数,因为我不希望开发人员每次都必须实现代码(因为他们可能会犯错误并丢失属性)

我可以看到两种选择

如果您的类型实现了
INotifyPropertyChanged
,则可以订阅对象的
PropertyChanged
事件,并使用该事件跟踪更改

否则,如果要在不更改属性代码的情况下实现此功能,则需要外部更改跟踪。您可以创建一个方法,使用反射(或潜在反射)获取每个属性的值,然后将其与当前值进行比较,以确定该对象是否“脏”。然而,这不是一个便宜的操作

另一个可能更优雅的选项是在编译时将代码自动添加到每个属性中。例如,可以让它相当容易地处理这个问题

这里有一个陷阱:我不想在每个setter中调用一些函数,因为我不希望开发人员每次都必须实现代码(因为他们可能会犯错误并丢失属性)

我可以看到两种选择

如果您的类型实现了
INotifyPropertyChanged
,则可以订阅对象的
PropertyChanged
事件,并使用该事件跟踪更改

否则,如果要在不更改属性代码的情况下实现此功能,则需要外部更改跟踪。您可以创建一个方法,使用反射(或潜在反射)获取每个属性的值,然后将其与当前值进行比较,以确定该对象是否“脏”。然而,这不是一个便宜的操作


另一个可能更优雅的选项是在编译时将代码自动添加到每个属性中。例如,可以相当容易地处理此问题。

最初将m_SomePropertyInFoo设置为null(在VB中为Nothing)。然后,当您想检查某个值是否已设置时,请检查它是否为null

您必须调整setter以返回String.Empty(如果值为null),否则您必须在下一层处理NullReference异常,这一点都不有趣。我的VB有点生锈了,但下面是:

dim m_SomePropertyInFoo as string = Nothing

public property SomePropertyInFoo as string
    get
        If m_SomePropertyInFoo Is Nothing Then
            return string.Empty
        Else
            return m_SomePropertyInFoo
        End If
    end get
    set(value as string)
        m_SomePropertyInFoo = value
    end set

最初将m_SomePropertyInFoo设置为null(VB中为Nothing)。然后,当您想检查某个值是否已设置时,请检查它是否为null

您必须调整setter以返回String.Empty(如果值为null),否则您必须在下一层处理NullReference异常,这一点都不有趣。我的VB有点生锈了,但下面是:

dim m_SomePropertyInFoo as string = Nothing

public property SomePropertyInFoo as string
    get
        If m_SomePropertyInFoo Is Nothing Then
            return string.Empty
        Else
            return m_SomePropertyInFoo
        End If
    end get
    set(value as string)
        m_SomePropertyInFoo = value
    end set

如果您不想对每个属性重新编码,有两个选项

  • 考虑使用一个框架,该框架可用于将代码自动编织到类中,从而实现更改跟踪,例如

  • 在第一次检索实例时对其进行序列化,在保存时对其进行序列化,并对字节进行比较


  • 1是最好的,而2可能又便宜又讨厌。

    如果您不想对每个属性重新编码,可以选择几个选项

  • 考虑使用一个框架,该框架可用于将代码自动编织到类中,从而实现更改跟踪,例如

  • 在第一次检索实例时对其进行序列化,在保存时对其进行序列化,并对字节进行比较


  • 1是最好的,而2可能又便宜又讨厌。

    一个选项是使用Castle DynamicProxy之类的运行时代理

    这是一篇博客文章,展示了“用DynamicProxy追踪肮脏”


    一个选项是使用Castle DynamicProxy之类的运行时代理

    这是一篇博客文章,展示了“用DynamicProxy追踪肮脏”


    假设属性为整数。假设原始值为4。代码将该值更改为0。在VB术语中,整数的零也为0。0是否脏?请使用可为空的类型:。0 != 这里什么都没有。我没有在这个例子中详细说明这一点,因为字符串本身就是可以为null的。这还需要在属性定义中添加代码,OP特别希望避免这种情况……可以为null的类型很好。但即使如此,如果更改后的值为null会怎样呢。在这一点上,我的工作假设初始值可能不是默认值,例如,如果您有一个对象表示可以修改和重新保存的预先存在的数据。神奇的值,甚至是可为null的值,可能都不会给你想要的行为。他特别说了setter,但是是的。假设属性是整数。假设原始值为4。代码将该值更改为0。在VB术语中,整数的零也为0。0是否脏?请使用可为空的类型:。0 != 这里什么都没有。我没有在这个例子中详细说明这一点,因为字符串本身就是可以为null的。这还需要在属性定义中添加代码,OP特别希望避免这种情况……可以为null的类型很好。但即使如此,如果更改后的值为null会怎样呢。在这一点上,我的工作假设初始值可能不是默认值,例如,如果您有一个对象表示可以修改和重新保存的预先存在的数据。魔法值,甚至可以是空值,都可能不会给你你想要的行为。好吧,他特别说了二传者,但是是的。我们提出了你的第二个建议作为一种选择。我们正在进行的辩论是必须复制记忆。但很高兴知道我们一直在沿着这些思路思考@