[英]How to refactor this decompiled C# code with invalid reference syntax?
反编译一个程序集后,它生成的代码产生了很多类似的方法:
internal long m_position;
internal void PutString(long RecordNumber, string s)
{
if (s == null)
s = "";
int byteCount = this.m_Encoding.GetByteCount(s);
this.SetRecord(RecordNumber);
this.LengthCheck(byteCount);
if (byteCount != 0)
this.m_sw.Write(s);
// ISSUE: variable of a reference type
long& local;
// ISSUE: explicit reference operation
long num = checked (^(local = ref this.m_position) + (long) byteCount);
local = num;
}
只有从// ISSUE
开始的代码有问题。 如您所见,它包含无效的语法long& local;
. 我找到了这个答案,它很好地解释了这是什么。 在阅读了 C# ref locals 之后,我尝试重构此方法以便它可以编译,但我没有成功。 ^(local = ref this.m_position)
部分真的很适合我,因为我在按位运算方面不是很强大。
有人可以帮我重构最后三行并向我解释它是如何工作的吗? 这种模式在反编译的代码中几乎逐字出现数百次,所以一旦我“理解”这个例子,我应该对它的 rest 没有问题。
这是 dotPeek 失败但 ILSpy 处理得很好的事情之一。 您看到的是+=
运算符的编译器优化。 而不是计算字段位置两次 - 一次获取值并再次存储它 - 编译器生成计算字段偏移量的代码,然后将其用于操作的两个部分。
您遇到问题的位(未知的^
运算符)很可能是 dotPeek 尝试显示 ref 变量的取消引用。 当然,在 C# 中这不是必需的,我们只使用变量本身的名称。
只需将其重写为:
m_position += byteCount;
编译器将决定是否要添加该特定优化。
long&
表示 long 的引用类型,应替换为ref long
。 然后将m_position
字段的地址分配给local
变量(使local
成为它的别名),然后在向其添加字节数时检查算术溢出。 不完全确定插入符号,在托管 C++ 中,它是指导 object GC 的帽子,所以我想这就是它在做什么。 当算术检查成功完成时,通过local
var 将m_position
字段设置为当前值加上byteCount
。
ref long local = ref this.m_position;
long num = checked(local + (long)byteCount);
local = num;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.