While implementing a custom settings provider I noticed that accessing a setting property's value changes its IsDirty
flag to true
.
// Arrange
var property = new SettingsProperty("property1")
{
PropertyType = typeof(Color),
DefaultValue = "Green"
};
// Act
var result = new SettingsPropertyValue(property);
// Assert
Assert.That(result.IsDirty, Is.False);
Assert.That(result.PropertyValue, Is.EqualTo(Color.Green));
Assert.That(result.IsDirty, Is.False); // <-- Assertion fails
Reflector gives me an answer to the question why the PropertyValue
getter is behaving like this - it contains a statement like the following:
if (_Value != null && !Property.PropertyType.IsPrimitive && !(_Value is string) && !(_Value is DateTime))
{
_UsingDefaultValue = false;
_ChangedSinceLastSerialized = true;
_IsDirty = true;
}
Can anybody shed some light on this at first glance strange behavior?
The documentation states that this is to account for any potential side effects of accessing the value when it is a complex type, as well as mutating the value without reassigning the value (for example when modifying the items in a list):
The IsDirty property is set to true under the following conditions:
[...]
The value contained in the SettingsPropertyValue object is accessed, and the value is not a string or a primitive type such as int, float, real, or DateTime. When the value managed by a SettingsPropertyValue object is a complex type (for example an ArrayList), there is no way for a SettingsPropertyValue object to detect when changes have been made. As a result, the SettingsPropertyValue object pessimistically assumes that a complex type is dirty once it has been accessed from the PropertyValue property.