I was looking through some code I wrote a while ago and realized I made an assumption about the assignment operator in C#. Here is the line of code in question (it works as expected):
pointsChecked = pointsChecked ?? new List<Point>();
pointsChecked
is a List specified as a parameter to a recursive function. It is a default parameter with default value null
. What I want to do is initialize it once and then build a collection of points that I have already checked, so it should only be initialized during the first iteration.
My assumption was that C# is guarded against self-assignment in the same way that C++ operator=
should provide a guard when overloaded (ie, if(this == &rightHandSide) return *this;
). However, I haven't been able to find any resources that explicitly state that this is true for C#.
The closest example I found was this question about the null-coalescing operator, where it appears that the object is assigned back to itself if it is not null
. No one said anything about the self-assignment in that example, but I want to be certain that this isn't a bad practice and that there are no negative side effects.
Searching on MSDN I also found that (paraphrasing based on my understanding) the value on the right hand side is copied over to the value on the left hand side and returned. So I am, again, unsure if it is a bad thing to do a self-assignment.
I know I could do the following to be safer:
if(pointsChecked == null)
{
pointsChecked = new List<Point>();
}
But I would rather understand what is actually happening with self-assignment.
Definition of self-assignment : the act of assigning something (such as a task) to oneself working on/by self-assignment also : the task or work that is assigned Alexander came to Winged Foot in 1959 to shoot the U.S. Open. It was a self-assignment that resulted in a series of iconic photos … — Mike Dougherty.
Self assignment is when someone assigns an object to itself. For example, #include "Fred.h" // Defines class Fred void userCode(Fred& x) { x = x; // Self-assignment }
The assignment operator = assigns the value of its right-hand operand to a variable, a property, or an indexer element given by its left-hand operand. The result of an assignment expression is the value assigned to the left-hand operand.
Assignment copies the reference to an object, not the object contents. No customizable code runs as part of an assignment to a variable holding an object reference, ever. This is also true for structs.
In C++ assignment is customizable, in C# it is not.
It is safe to assign the same object reference to a variable already holding it:
object someRef = new object();
someRef = someRef; //always does nothing
This is as safe as assigning any other value:
int someVal = 123;
someVal = someVal; //always does nothing
Note, that no general way exists to clone/copy an object. Any explanation relying on the presence of such a mechanism must be wrong.
Self-assignment is safe because it translates to the following approximate IL instructions:
ldloc someRef
stloc someRef
This has clearly defined semantics. It first loads someRef
onto the stack, then stores whatever is on the stack to someRef
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With