I've just decompiled some 3rd party source to debug an issue, using DotPeek. The output code contains some unusual operators, which AFAIK aren't valid C#, so I'm wondering what they mean...
The extract looks like (with Dotpeek comments included, as they are probably relevant);
protected internal void DoReceive(ref byte[] Buffer, int MaxSize, out int Written)
{
Written = 0;
.
.
.
// ISSUE: explicit reference operation
// ISSUE: variable of a reference type
int& local = @Written;
int num = SomeMethod();
.
.
.
// ISSUE: explicit reference operation
^local = num;
}
So, 3 unusual operators in there... int& = @Written
seems to be assigning a pointer to a variable that is named pointlessly with the @ character?
But what is ^local = num;
???
OK, here is the equivalent snippet from ILSpy, which makes more sense, I guess the decompile to C# didn't produce a valid equivalent?
'C#'
int& local = @Written;
byte[] numArray2 = this.FInSpool;
int num = (int) __Global.Min(numArray2 == null ? 0L : (long) numArray2.Length, (long) MaxSize);
^local = num;
IL
byte[] expr_22 = this.FInSpool;
Written = (int)__Global.Min((long)((expr_22 == null) ? 0 : expr_22.Length), (long)MaxSize);
So, I guess the 'C#' isn't quite valid? That IL would be valid C#, not sure why DotPeek produced the output it did. Perhaps I'll stick to ILSpy for this one...?
If you look at the raw IL (from ildasm, not the C# equivalent via IL Spy), that may help you see what the decompiler is trying to say. 'Out' parameters are represented using a (managed) typed-reference, which isn't explicitly exposed as a type in C#. 'Instances' of this type can normally only be passed as parameters to methods accepting typed references ('ref' or 'out' parameters.) See OpCodes.Mkrefany for more information.
What dotPeek is complaining about is that this 'out' typed reference was stored from the argument into a local variable slot, then written to later via the local slot. The '@' and '^' are placeholders used to indicate this unexpected behavior detected by the decompiler (the one the ISSUE comments describe.)
It's possible the code was compiled from C++/CLI and thus the IL looks different from the typical C# compiler output. It's also possible this is some level of minor obfuscation to confuse decompilers (though I don't think so.) I don't think this is functionally any different from loading the reference from its argument onto the operation stack directly (avoiding the use of a local variable slot), but I could be wrong.
Putting a @
before a name allows you to use a reserved name for a variable, For example if I wanted to have a variable called return
I would need to do this.
public int Weird()
{
int @return = 0;
return @return;
}
See this SO question for more details.
Putting a ^
before the name ... umm, no clue. (will update as I research I could find any info on what ^
means when not being used as a XOR)
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