为什么“DisplayClass”和调用方法名称在堆栈跟踪中以这种方式排序?

时间:2022-05-13 19:55:15

First of all, I've read this answer and no, it only says how it is implemented right now, but doesn't explain why.

首先,我已经阅读了这个答案而不是,它只是说它现在如何实现,但没有解释原因。

Here's a sample program (same as here):

这是一个示例程序(与此处相同):

class Program
{
    static void Main()
    {
        try {
            implMain();
        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }
    }

    static void implMain()
    {
        for (int i = 0; i < 10; i++) {
            invoke(() => {
                Console.WriteLine(i);
                throw new InvalidOperationException();
            });
        }
    }
    static void invoke(Action what)
    {
        what();
    }
}

which outputs the following call stack:

它输出以下调用堆栈:

System.InvalidOperationException
at ConsoleApplication1.Program.<>c__DisplayClass2.<implMain>b__0()
at ConsoleApplication1.Program.invoke(Action what)
at ConsoleApplication1.Program.implMain()
at ConsoleApplication1.Program.Main()

Note these two lines:

请注意以下两行:

at ConsoleApplication1.Program.<>c__DisplayClass2.<implMain>b__0()
at ConsoleApplication1.Program.invoke(Action what)

The lower one (with invoke()) says that there's namespace ConsoleApplication1 with class Program in it that has member invoke(). Here left-to-right corresponds to outer-to-inner.

较低的一个(使用invoke())表示其中包含具有成员invoke()的类Program的命名空间ConsoleApplication1。这里从左到右对应于从外到内。

The upper one (with c__DisplayClass2) says again there's a namespace and a class...

上面一个(用c__DisplayClass2)再说一个命名空间和一个类......

and then there's c__DisplayClass2 which means "a magic name the compiler chosen for storing captured variables" and then there's <implMain> as if it is a parameter to c__DisplayClass2. So it reads as if c__DisplayClass2 somehow is part of Program and implMain is part of c__DisplayClass2.

然后是c__DisplayClass2,意思是“编译器选择用于存储捕获变量的魔术名称”,然后 就好像它是c__DisplayClass2的参数一样。所以它看起来好像c__DisplayClass2不知何故是Program的一部分而implMain是c__DisplayClass2的一部分。

Now as I see it it's logically the opposite - there's implMain() method and there's "magic class" c__DisplayClass2 crafted specifically for implMain() local variables. So to me it looks like the upper line should look like this:

现在我认为它在逻辑上恰恰相反 - 有implMain()方法,并且有专门针对implMain()局部变量的“魔术类”c__DisplayClass2。所以对我来说,上面的行看起来应该是这样的:

at ConsoleApplication1.Program.implMain.c__DisplayClass2.b__0()

(maybe with some extra symbols to prevent possible conflicts) but I hope my idea is clear - this way it would look like c__DisplayClass2 is crafted specifically to facilitate implMain() functioning.

(可能有一些额外的符号来防止可能的冲突)但我希望我的想法很明确 - 这样看起来像c__DisplayClass2是专门为促进implMain()功能而精心设计的。

Is there any reason why the current implementation shows the method name (implMain) after the local variables capture class name (c__DisplayClass2) and not vice versa?

是否有任何理由说明当前实现在局部变量捕获类名(c__DisplayClass2)之后显示方法名称(implMain)而反之亦然?

1 个解决方案

#1


3  

<implMain>b__0() is just the name of the method.

b__0()只是方法的名称。

Inspection in a disassembler will show you this. The < and > does not imply generics.

在反汇编程序中检查将向您显示此信息。 <和> 并不意味着泛型。

The inclusion of implMain probably just hints where the delegate was created.

包含implMain可能只是提示创建委托的位置。

#1


3  

<implMain>b__0() is just the name of the method.

b__0()只是方法的名称。

Inspection in a disassembler will show you this. The < and > does not imply generics.

在反汇编程序中检查将向您显示此信息。 <和> 并不意味着泛型。

The inclusion of implMain probably just hints where the delegate was created.

包含implMain可能只是提示创建委托的位置。