While I was working on some of older code in C#, I encountered a code which irked me.
There are numerous irksome problems here. Let's list them all.
It's the last line which irks me
The comment is also irksome. Local variables are cheap. There is no need to erase the original value of . Instead, make a new local variable and manipulate that. That way, when you are debugging at any point in the method you can know what the original argument was. (Remember, the original argument might be eligible for garbage collection the moment the variable is overwritten, and therefore could be lost forever.)
Do not write over a formal parameter without a very good reason. It makes it harder to debug.
the value of an assignment operator is the left operand, so I can see it.
That is correct in this case but subtly wrong in general; the value of an assignment operator in C# is the value of the right operand after being converted to the type associated with the left hand side. Remember, the left hand side might not have a value; it could be a write-only property.
Is it a ordinate practice in C# that I need to get accustomed to?
There is a standard practice here, yes. What is bizarre about this usage is (1) that the variable chosen is a formal, and (2) that the assignment is combined with the .
It would be a standard practice in C# to say:
Now you might wonder what the compelling benefit of this is over what you suggest:
The answer is: before Visual Studio 2013, there was no facility in the debugger to examine the returned value of a method call! Therefore if you wanted to see what the value returned by was while debugging you had the following choices:
- Debug at the assembly level and look at the contents of EAX
- Step into and examine its state
- Step out of the current method and examine whatever the return value was assigned to
- Assign the result to an otherwise useless local variable and then examine the local in the debugger
Since the first three are horrid and the last one is easy, that's what many C# programmers got in the habit of doing.
If you do this and then do not use the resulting local, the C# compiler knows that this is a common practice and deliberately suppresses the "you wrote to a local you then never read from" warning. It only gives that warning if the local had a constant written to it, in which case you already knew what it was at compile time and don't typically need to examine it in the debugger.
Hopefully now that VS2013 finally supports this frequently-requested feature, this sort of pattern will gradually disappear.
The general answer to all questions about "why was this language feature not implemented" is that the team who designed the language decided that the benefit didn't outweigh the cost.
Cost can take many forms. It takes time and effort to implement a language feature, but there is also the intrinsic cost of complexity: does the feature make the language more complex or ambiguous, out of proportion to its potential benefit?
The hypothetical operator does something fundamentally different from the other compound assignment operators. While the other operators are purely mathematical in nature, this one is different: it substitutes one value for another (in the context you described).
Given this ambiguity (the operator performs two different functions, depending on context), it's not difficult to see why it was not included in the language. Although you state that changing
to perform null coalescing is a valuable feature, the benefit is far less clear to me. If value substitution is to occur, it seems logical (and clearer) to have both values on the right side of the equals sign, to provide a visual indication that such substitution may occur.
C# took a different path, and uses a specific operator for null coalescing.