提问人:Trent Adams 提问时间:11/14/2023 最后编辑:gunr2171Trent Adams 更新时间:11/14/2023 访问量:99
反编译源代码时出现奇怪的字符 [已关闭]
Getting a weird character when decompiling source code [closed]
问:
尝试反编译应用程序时,我得到一个矩形框。我不确定是否有办法解释这是什么。
public void Add(MessageErrorCode errorCode);
public void Add(SegmentErrorContext segmentContext);
public void AddRange(IEnumerable<MessageErrorCode> errorCodes);
public void AddRange(IEnumerable<SegmentErrorContext> segmentContexts);
[IteratorStateMachine(typeof())]
public IEnumerable<string> Flatten();
public void Sort();
答:
2赞
NineBerry
11/14/2023
#1
该属性由编译器添加到生成的 IL 机器代码中,用于内部使用的“迭代器”方法。IteratorStateMachine
yield
只需删除该属性即可使代码正常工作。
为了说明这一点,请看这个 SharpLab 要点:https://sharplab.io/#gist:fc2cc09bb9cf72774eb724d655613cbf
代码
using System;
using System.Collections.Generic;
public class C
{
public IEnumerable<int> M()
{
yield return 0;
yield return 1;
}
}
翻译成 IL 机器代码,如下所示:
[IteratorStateMachine(typeof(<M>d__0))]
public IEnumerable<int> M()
{
<M>d__0 <M>d__ = new <M>d__0(-2);
<M>d__.<>4__this = this;
return <M>d__;
}
2赞
Dawnkeeper
11/14/2023
#2
它是由编译器添加的。
不应将该特性应用于代码中的方法。对于 Visual Basic 中具有 Iterator 修饰符的方法,编译器将在它发出的 IL 中应用该属性
IteratorStateMachine
IteratorStateMachine
来自 Microsoft 文档。
1赞
Olivier Jacot-Descombes
11/14/2023
#3
C# 对标识符有严格的命名规则。链接的文档说:
- 标识符必须以字母或下划线 () 开头。
_
- 标识符可以包含 Unicode 字母字符、十进制数字字符、Unicode 连接字符、Unicode 组合字符或 Unicode 格式字符。有关 Unicode 类别的详细信息,请参阅 Unicode 类别数据库。
声明的元素名称 (Visual Basic) 与此类似。以下情况也适用于 VB。
C# 编译器将 C# 代码文本转换为 IL。IL 允许使用任何类型的标识符。特别是它可以包含不被视为字母、数字或下划线的特殊字符。ECMA 335,第 5 版,分区 II,第 5.3 节(PDF 第 135 页)指出:
- ILAsm 语法 允许使用任何可通过 Unicode 字符集形成的标识符(请参阅分区 I)。为了实现 这,标识符应放在单引号内。
对于编译器生成的对象(方法、类等),会创建不是有效 C# 标识符的标识符,以避免与代码中存在的标识符发生冲突。
因此,如果反编译代码(从 IL 到 C#)包含奇怪的标识符,请不要感到惊讶。
评论
0赞
Trent Adams
11/14/2023
感谢大家的建议和帮助。非常感谢。
0赞
Trent Adams
11/15/2023
那么,在浏览反编译代码并注意到这些字符时,我该怎么办?可以这么说,这让我们陷入了泥潭,不是吗?
1赞
Olivier Jacot-Descombes
11/15/2023
反编译的代码从来都不是完美的。例如,局部变量的名称和注释在编译时丢失。一些语言结构被称为“句法糖”,并由编译器翻译成更基本的语言结构。此外,编译器可以自由地进行优化。因此,反编译的代码很少看起来与原始代码完全相同。如果要使用反编译的代码,并且遇到无效的标识符,请使用查找/替换将其替换为有效的标识符。
评论