Reputation: 11
I have this code:
private static void Tokenize(RichTextLabel Log,string commandString){
Log.Text += "\n&";
int[] tokens = new int[5];
int current = 0;
while (current < commandString.Length){
switch (commandString[current]){
case ' ':
Log.Text += "+";
break;
default:
Log.Text += "_";
break;
}
current++;
}
Log.Text += "\n";
}
And when i look at the "compiled code" (Low-level C# in rider's IL Viewer) which i know is not perfect or accurate in all cases. But this is what it produces:
private static void Tokenize(RichTextLabel Log, string commandString)
{
RichTextLabel richTextLabel1 = Log;
richTextLabel1.Text = string.Concat(richTextLabel1.Text, "\n&");
int[] tokens = new int[5];
for (int current = 0; current < commandString.Length; ++current)
{
if (commandString[current] == ' ')
{
RichTextLabel richTextLabel2 = Log;
richTextLabel2.Text = string.Concat(richTextLabel2.Text, "+");
}
else
{
RichTextLabel richTextLabel3 = Log;
richTextLabel3.Text = string.Concat(richTextLabel3.Text, "_");
}
}
RichTextLabel richTextLabel4 = Log;
richTextLabel4.Text = string.Concat(richTextLabel4.Text, "\n");
}
As you can see, it produces 4 repetitive RichTextLabel richTextLabel = Log;
My question is, is this accurate? If so why does it need to re-reference the object multiple times?
Upvotes: 0
Views: 60
Reputation: 71544
This is mostly an accurate representation of what is going on, except that I think the variable doesn't actually exist.
12.21.4 Compound assignment
An operation of the form
x «op»= y
is processed by applying binary operator overload resolution (§12.4.5) as if the operation was writtenx «op» y
. Then,
- If the return type of the selected operator is implicitly convertible to the type of x, the operation is evaluated as
x = x «op» y
, except thatx
is evaluated only once (my bold).- Otherwise, ..... the operation is evaluated as
x = (T)(x «op» y)
, whereT
is the type ofx
, except thatx
is evaluated only once.
And since the compiler doesn't know what Log
does, to prevent the getter and setter potentially referring to different objects, it just caches it in a hidden variable.
Having said all that, looking at the generated IL in Sharplab shows that a dup
opcode is used, so instead of caching it in a variable, it actually caches it in the stack. So Rider might just be generating a variable in order to represent the same semantics in psueudo-C#. The effect and performance should be the same though, and you shouldn't expect that the compiler will necessarily use one form over the other.
Upvotes: 1