Objects in the Windows Runtime can have properties, and those properties could be read-only or read-write. For read-write properties, there are a few general principles. Today we’re going to look at this one:
- Setting a property to its current value is legal and has no effect.¹
For example:
// C# o.Color = o.Color; // C++/WinRT o.Color(o.Color());
We are setting a property’s value to the value it already has.
Now, this may look like a pointless thing to write on its own, but it could fall out of other code.
// C# o.Color = EnsureSufficientContrast(o.Color, m_backgroundColor); // C++/WinRT o.Color(EnsureSufficientContrast(o.Color(), m_backgroundColor);
The hypothetical EnsureÂSufficientÂContrast function returns a foreground color that provides sufficient contrast against a background color. It’s possible that the existing foreground color already provides sufficient contrast, in which case the original color is returned unaltered.
This principle seems obvious, but it comes with corollaries.
- Corollary: Setting a property twice to the same value has no effect.
Setting the property multiple times is the same as setting it once.
I remember many years ago I was looking at a customer program, and they had a property called Print. Setting it to True caused a document to print. I don’t mean that it resulted in a printout happening when you submitted the document. I mean it printed the document at the moment you set the Print property. If you wanted to print two copies, you would do
document.Print = True ' Print it document.Print = True ' Print it again
This was definitely a violation of the idempotence principle. As well as a violation of other principles like “What were you thinking?”
Next time, I’ll look another simple corollary to the idempotence principle that people often are tempted to violate.
¹ By “no effect” here, I mean no functional effect. Clearly the code runs more slowly because you’re performing a redundant operation, and there might be follow-on calculations that occur when the property is set. But the point is that the correctness of the program is not affected by the redundant write to the property.
Feel your pain if it was a contracter. If it was a student hire then In other news, old man yells at cloud.
Re: raising events. Only if the event design principle allows coalescing. I guess that could be.
Re: access check. The access model isn’t all-or-nothing. Maybe the current caller is allowed to write 1 or 2, but the property currently has value 3.
I guess the easiest violation is to fire (property changing) events for assigning the current value. One leaving me undecided is checking access before accepting an assignment.
Raising a “Property changed” event is fine. After all, the recipient has to deal with the possibility that the property changed from X to Y, then back to X.
Access checks are also fine. Because if you fail the access check, then the property wasn’t writable after all!
This kind of reminds me about a time that component violates this principal because of the way ShowCursor() and HideCursor() works, although you could also say the component should check the value of .ShowCursor before deciding whether to call the APIs, which ultimately is the fix.
On the subject of "what were you thinking" violations, I once had to fix some code we had gotten from a contractor. This was in the days before widespread adoption of the standard library, so the contractor decided they needed to implement their own container type. Whoever got the job of implementing it was obviously using the contract as an excuse to learn C++, and had just gotten to the chapter on operator overloading in their "C++ in a week for complete idiots" book, because they used operator overloading for anything they could get away with.
This container was a sorted...
I think I have seen some VBX components that showed their About boxes on some property assignment. Probably because property assignment is pretty much all you can do to a component right from the form designer.