This can be applied to many different languages, but I am specifically working with C# and INotifyPropertyChanged.
If a property is set, should I re-assign its value even if it did not change?
For example:
public int IntProperty
...
set
{
var oldValue = _intProperty;
_intProperty = value;
if (!Equals(value, oldValue))
{
OnPropertyChanged(...);
}
}
vs.
public int IntProperty
...
set
{
if (!Equals(value, _intProperty))
{
_intProperty = value;
OnPropertyChanged(...);
}
}
I just can’t decide. Technically, it shouldn’t make a difference, but there are some odd corner cases (like strange Equals implementations that should never happen) that could change the behavior.
This can be influenced by the type of the property. Some classes have intelligent Equals methods, and some don’t. If you trust yours, it shouldn’t matter, but if the class doesn’t override Equals, or doesn’t do it well, then it changes things. On the whole, I’d say that the underlying value shouldn’t change without the notification being sent, so I’d go with #2.
To give an example, maybe there’s a simple data holder looking something like this:
Now if ID is supposed to be unique (possibly because it maps to a DB ID value) then this isn’t that bad of an idea, but it doesn’t stop people from going around creating objects with the same ID and different data values. If some mean person did that you could end up setting a value to a property such as your in which the new value really is significantly different, but .Equals will say they are the same. Now no matter what happens here you’re somewhat screwed, but which is worse, not setting a value that shouldn’t be different but is (because the set is inside the if) or changing the value and not notifying event subscribers that the event changed? (You also have the third option of setting the event and notifying people even if it changed, possibly indicated that this is the case via the event args.) If an event subscriber is code that persists the change to the database (which is often the case with this type of structure) then you’re changing a value in memory, thinking that it really changed (getting it back out is an exact reference match), but the value still won’t be persisted because the event wasn’t fired.
Sorry for the wall of text.
tl;dr version, users of this code can find a way to screw you no matter what you do; eventually you need a minimal amount of trust in them for your code to be effective.