考虑以下对象:
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
的实例变为脏。这里有一个问题:我不想在每个setter中调用一些函数,因为我不希望devs每次都必须实现代码(因为它们可能会出错并错过属性)。
答案 0 :(得分:2)
一个选项是使用像Castle DynamicProxy
这样的运行时代理http://www.castleproject.org/services/index.html
这是一篇博文,显示“使用DynamicProxy追踪肮脏”
答案 1 :(得分:1)
如果您不想重新编码每个属性,请选择几个选项。
考虑使用一个框架,该框架可用于自动将代码编织到您的类中,以实现更改跟踪,例如PostSharp
首次检索实例时序列化实例,在保存实例时对其进行序列化,并对字节进行比较。
1是优选的,而2便宜且讨厌。
答案 2 :(得分:0)
这是一个问题:我不想在每个setter中调用某个函数,因为我不希望devs每次都必须实现代码(因为它们可能会出错并错过属性)。
我可以看到两种选择。
如果您的类型实现了INotifyPropertyChanged
,您可以订阅该对象的PropertyChanged
事件,并使用它来跟踪更改。
否则,如果您想要实现此而不更改属性代码,则需要进行外部更改跟踪。您可以创建一个方法,使用Reflection(或可能PropertyDescriptors)来获取每个属性的值,然后将其与当前值进行比较,以确定该对象是否“脏”。然而,这不是一个廉价的操作。
另一个可能更优雅的选择是使用Aspect Oriented Programming在编译时自动将代码添加到每个属性。例如,PostSharp可以很容易地处理这个问题。
答案 3 :(得分:0)
最初将m_SomePropertyInFoo设置为null(VB中为Nothing)。然后,当您想检查是否已设置值时,请检查它是否为空。
如果值为null,则必须调整setter以返回String.Empty,否则你将不得不在下一层中处理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