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?
This is mostly an accurate representation of what is going on, except that I think the variable doesn't actually exist.
The C# spec states:
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.