反编译源代码时出现奇怪的字符 [已关闭]

Getting a weird character when decompiling source code [closed]

提问人:Trent Adams 提问时间:11/14/2023 最后编辑:gunr2171Trent Adams 更新时间:11/14/2023 访问量:99

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

9天前关闭。

尝试反编译应用程序时,我得到一个矩形框。我不确定是否有办法解释这是什么。

 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();
反编译器 C#-10.0

评论

2赞 Daniel A. White 11/14/2023
这可能只是一个编译器生成的属性。
0赞 Wyck 11/14/2023
该字符是 U+E000(专用代码点)。这是否“奇怪”是主观的。

答:

2赞 NineBerry 11/14/2023 #1

该属性由编译器添加到生成的 IL 机器代码中,用于内部使用的“迭代器”方法IteratorStateMachineyield

只需删除该属性即可使代码正常工作。

为了说明这一点,请看这个 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 中应用该属性IteratorStateMachineIteratorStateMachine

来自 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
反编译的代码从来都不是完美的。例如,局部变量的名称和注释在编译时丢失。一些语言结构被称为“句法糖”,并由编译器翻译成更基本的语言结构。此外,编译器可以自由地进行优化。因此,反编译的代码很少看起来与原始代码完全相同。如果要使用反编译的代码,并且遇到无效的标识符,请使用查找/替换将其替换为有效的标识符。