反编译源中不寻常的C#运算符......?

RJ *_*han 14 c# syntax dotpeek

我刚刚使用DotPeek反编译了一些第三方来源来调试问题.输出代码包含一些不常见的操作符,AFAIK无效C#,所以我想知道它们是什么意思...

摘录看起来像(包括Dotpeek评论,因为它们可能相关);

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;
}
Run Code Online (Sandbox Code Playgroud)

那么,那里有3个不寻常的操作符...... int& = @Written似乎是在指定一个用@字符无意义命名的变量的指针?

但是什么是^local = num;???

好的,这是来自ILSpy的等效片段,这更有意义,我想反编译到C#没有产生有效的等价物?

'C#'

 int& local = @Written;
 byte[] numArray2 = this.FInSpool;
 int num = (int) __Global.Min(numArray2 == null ? 0L : (long) numArray2.Length, (long) MaxSize);
 ^local = num;
Run Code Online (Sandbox Code Playgroud)

IL

 byte[] expr_22 = this.FInSpool;
 Written = (int)__Global.Min((long)((expr_22 == null) ? 0 : expr_22.Length), (long)MaxSize);
Run Code Online (Sandbox Code Playgroud)

那么,我猜'C#'不是很有效?IL将是有效的C#,不知道为什么DotPeek会产生它的输出.也许我会坚持ILSpy这个......?

Dan*_*ant 9

如果你看一下原始的IL(来自ildasm,而不是通过IL Spy的C#等价物),这可能会帮助你看到反编译器试图说的内容."Out"参数使用(托管)类型引用表示,该引用未在C#中显式公开为类型.此类型的"实例"通常只能作为参数传递给接受类型引用的方法('ref'或'out'参数.)有关详细信息,请参阅OpCodes.Mkrefany.

dotPeek抱怨的是这个'out'类型的引用从参数存储到局部变量槽中,然后通过本地槽写入.'@'和'^'是占位符,用于表示反编译器检测到的这种意外行为(ISSUE注释描述的行为).

代码可能是从C++/CLI编译的,因此IL看起来与典型的C#编译器输出不同.也有可能这是混淆反编译器的某种程度的轻微混淆(虽然我不这么认为.)我不认为这在功能上与将参数从其参数直接加载到操作堆栈上有所不同(避免使用一个局部变量槽),但我可能是错的.

  • 实际上,我错过了一些; 您的示例中的特定方法可能不使用类型引用(通过mkrefany),而是地址引用(即类型int&).也就是说,基本问题仍然是一样的; 反编译器在使用之前不期望int&被存储到局部变量中. (2认同)