IME, the most common way properties are used is that the setter validates the new property value, stores it in a member variable, and often calls an API or some other function to let it know the property has changed (e.g. updating a button caption on the screen), and the getter simply reads the property value from the member variable. Therefore, reading the property value is almost always a trivial operation.
Unfortunately, you’re also guaranteed that every piece of code that uses your class will break if you ever decide you need a function call after all.
Suppose you’re writing a text box that can be toggled between single and multiple lines, so you make a boolean property MultiLine. For optimization purposes, you make it a public member variable, and in your keyboard event handler, you simply ignore the enter key if MultiLine is false.
Then a few months later, you decide you don’t want anyone to disable MultiLine if the box already contains line breaks. Or you change the look of the control so that it needs to be redrawn when MultiLine changes. Uh oh… that means writing a setter function, and rewriting all the existing code that uses that class.
The problem with those is you end up learning new syntax for every function that behaves like that. Since you can’t write one function that can accept a combination of strings, numbers, and objects, you end up with several functions that work together to do the same thing and need to be stuck together with operator overloading… and as you’ve illustrated, different libraries use different operators for the same thing. (AFAIK, generics in C# aren’t implicitly instantiated, so you can’t do this in C#.)
Now, I’ve looked at Boost and I’m impressed with the way they’ve been able to tortu–I mean, extend the language with templates ;), but I sure wouldn’t want to write something like that myself. It’s much easier to loop through a list and call ToString() on all the elements than to make all those templates and operators work together.
And a function that takes different parameter types is just one example. A single root class also lets you combine different types in a single array, like the list of items in a list box.
It’s not an implicit cast, it only happens when you call ToString(). And while you need an explicit cast in C# (just like in Delphi), in MC++ you can implicitly cast a __value enum to an integer.
Besides, ToString() is an excellent debugging tool, and comes in handy at other times - like the aforementioned list of items in a list box. You can toss strings, integers, and objects in the list box, and they’ll all be converted to strings when they’re displayed.
Proper coding of the Dispose method is what protects you against double Dispose().
Do you have a link where this is documented? I haven’t worked much with Java, but my understanding is that setting an object’s last reference to null only makes it available for GC, as in .NET; it doesn’t force immediate finalization or GC.