The summer is rather slow when it comes to development (hopefully we passed 35°C zone) but I am doing good progress with cleaning the code anyway.
One thing that stopped me was C#
struct. Most of the time I work with
classes and despite I know what the
struct is, I simply don’t have vast practice with it, and so I was caught off-guard.
I was implementing
Option which should work as
Nullable for all types. Since it should express strictly the notion of an option, it has to be a
struct (otherwise you would have to deal with missing option, unset option and set option with missing value — tad too much). Implementing it was no brainer, thanks to C# properties next to
SetValue I added nice
Value setter which changes
HasValue as well. Concise, easy to understand and… completely wrong.
I added it to Skila and to my surprise on one end I called
SetValue just to observe no value was ever set on the other end. What on the Earth? Well,
struct is always passed by value, which means that if
Option is returned from property getter or a method, there is a copy returned of real data. I could call
SetValue million times and it would not change a thing for stored data (only local, temporary, copy of
Option would be changed).
So rule of thumb for C# developer — by default make your
structs immutable. For a language/framework designer there is a lesson too — don’t make risky features implicit.
I‘ve recently watched “Essential Truths Everyone Should Know about Performance in a Large Managed Codebase” by Dustin Campbell. It is longer version of an old saying “profiler is your friend” — but what struck me while watching it is that in C# you don’t see bottlenecks. Boxing? Implicit. Unboxing? Implicit. Method wrapping (with boxing)? Implicit.
Add to this a framework which uses
object too often, and profiler becomes necessity. And I thought implicit conversion constructors in C++ were bad — boy, you can at least make them explicit by yourself.