According to this answer when code uses local variables from inside lambda methods the compiler will generate extra classes that can have name such as c__DisplayClass1
. For example the following (completely useless) code:
根据这个答案,当代码使用lambda方法中的局部变量时,编译器将生成可以有名称的额外类,如c__DisplayClass1。例如以下(完全无用的)代码:
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();
}
}
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 that there's c__DisplayClass2
in there which is a name of a class generated by the compiler to hold the loop variable.
注意,其中有c__DisplayClass2,它是编译器生成的用于保存循环变量的类的名称。
According to this answer c__DisplayClass
"means"
根据这个答案c__DisplayClass "意思是"
c --> anonymous method closure class ("DisplayClass")
c——>匿名方法闭包类(“DisplayClass”)
Okay, but what does "DisplayClass" mean here?
好的,但是“DisplayClass”是什么意思呢?
What does this generated class "display"? In other words why is it not "MagicClass" or "GeneratedClass" or any other name?
这个生成的类“显示”是什么?换句话说,为什么它不是“MagicClass”或“GeneratedClass”或其他名称?
3 个解决方案
#1
27
From an answer to a related question by Eric Lippert:
从Eric Lippert对相关问题的回答:
The reason that a closure class is called "DisplayClass" is a bit unfortunate: this is jargon used by the debugger team to describe a class that has special behaviours when displayed in the debugger. Obviously we do not want to display "x" as a field of an impossibly-named class when you are debugging your code; rather, you want it to look like any other local variable. There is special gear in the debugger to handle doing so for this kind of display class. It probably should have been called "ClosureClass" instead, to make it easier to read disassembly.
闭包类被称为“DisplayClass”的原因有点不幸:调试器团队使用这种术语来描述在调试器中显示有特殊行为的类。显然,我们不希望在调试代码时将“x”显示为不可能命名的类的字段;相反,您希望它看起来像任何其他局部变量。调试器中有一些特殊的设备可以处理此类显示类。它可能应该被称为“ClosureClass”,以便更容易阅读拆解。
#2
7
You can get some insight from the C# compiler source as available from the SSCLI20 distribution, csharp/sccomp subdirectory. Searching the code for "display" gives most hits in the fncbind.cpp source code file. You'll see it used in code symbols as well as comments.
您可以从SSCLI20发行版c#编译器源代码中获得一些见解,csharp/sccomp子目录。在fncbind中,为“display”搜索代码会获得最多的点击率。cpp源代码文件。您将在代码符号和注释中看到它的使用。
The comments strongly suggest that this was a term used internally by the team, possibly as far back as the design meetings. This is .NET 2.0 vintage code, there was not a lot of code rewriting going on yet. Just iterators and anonymous methods, both implemented in very similar ways. The term "display class" is offset from "user class" in the comments, a clear hint that they used the term to denote auto-generated classes. No strong hint why "display" was favored, I suspect that it might have something to do with these classes being visible in the metadata of the assembly.
这些评论强烈地表明,这是团队内部使用的术语,可能可以追溯到设计会议。这是。net 2.0标准代码,还没有很多代码重写。只是迭代器和匿名方法,它们以非常相似的方式实现。术语“显示类”与注释中的“user类”相抵消,这是他们使用术语表示自动生成类的明确提示。没有强烈的暗示为什么要“display”,我怀疑它可能与在程序集的元数据中可见的这些类有关。
#3
6
Based on Reflector, DisplayClass can be translated as CompilerGeneratedClass
基于Reflector, DisplayClass可以被翻译成编译器类。
[CompilerGenerated]
private sealed class <>c__DisplayClass16b
{
// Fields
public MainForm <>4__this;
public object sender;
// Methods
public void <cmdADSInit_Click>b__16a()
{
ADS.Initialize();
this.<>4__this._Sender = this.sender;
this.<>4__this.SelectedObject = ADS.Instance;
}
}
#1
27
From an answer to a related question by Eric Lippert:
从Eric Lippert对相关问题的回答:
The reason that a closure class is called "DisplayClass" is a bit unfortunate: this is jargon used by the debugger team to describe a class that has special behaviours when displayed in the debugger. Obviously we do not want to display "x" as a field of an impossibly-named class when you are debugging your code; rather, you want it to look like any other local variable. There is special gear in the debugger to handle doing so for this kind of display class. It probably should have been called "ClosureClass" instead, to make it easier to read disassembly.
闭包类被称为“DisplayClass”的原因有点不幸:调试器团队使用这种术语来描述在调试器中显示有特殊行为的类。显然,我们不希望在调试代码时将“x”显示为不可能命名的类的字段;相反,您希望它看起来像任何其他局部变量。调试器中有一些特殊的设备可以处理此类显示类。它可能应该被称为“ClosureClass”,以便更容易阅读拆解。
#2
7
You can get some insight from the C# compiler source as available from the SSCLI20 distribution, csharp/sccomp subdirectory. Searching the code for "display" gives most hits in the fncbind.cpp source code file. You'll see it used in code symbols as well as comments.
您可以从SSCLI20发行版c#编译器源代码中获得一些见解,csharp/sccomp子目录。在fncbind中,为“display”搜索代码会获得最多的点击率。cpp源代码文件。您将在代码符号和注释中看到它的使用。
The comments strongly suggest that this was a term used internally by the team, possibly as far back as the design meetings. This is .NET 2.0 vintage code, there was not a lot of code rewriting going on yet. Just iterators and anonymous methods, both implemented in very similar ways. The term "display class" is offset from "user class" in the comments, a clear hint that they used the term to denote auto-generated classes. No strong hint why "display" was favored, I suspect that it might have something to do with these classes being visible in the metadata of the assembly.
这些评论强烈地表明,这是团队内部使用的术语,可能可以追溯到设计会议。这是。net 2.0标准代码,还没有很多代码重写。只是迭代器和匿名方法,它们以非常相似的方式实现。术语“显示类”与注释中的“user类”相抵消,这是他们使用术语表示自动生成类的明确提示。没有强烈的暗示为什么要“display”,我怀疑它可能与在程序集的元数据中可见的这些类有关。
#3
6
Based on Reflector, DisplayClass can be translated as CompilerGeneratedClass
基于Reflector, DisplayClass可以被翻译成编译器类。
[CompilerGenerated]
private sealed class <>c__DisplayClass16b
{
// Fields
public MainForm <>4__this;
public object sender;
// Methods
public void <cmdADSInit_Click>b__16a()
{
ADS.Initialize();
this.<>4__this._Sender = this.sender;
this.<>4__this.SelectedObject = ADS.Instance;
}
}