.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会怎样呢。在这一点上,我的工作假设初始值可能不是默认值,例如,如果您有一个对象表示可以修改和重新保存的预先存在的数据。魔法值,甚至可以是空值,都可能不会给你你想要的行为。好吧,他特别说了二传者,但是是的。我们提出了你的第二个建议作为一种选择。我们正在进行的辩论是必须复制记忆。但很高兴知道我们一直在沿着这些思路思考@