C# 如果Int32只是int的别名,那么Int32类如何使用int?
一直在浏览.NET的源代码,只是为了好玩。发现了一些我不明白的东西 有一个Int32.cs文件,其C代码表示C# 如果Int32只是int的别名,那么Int32类如何使用int?,c#,compiler-construction,internals,C#,Compiler Construction,Internals,一直在浏览.NET的源代码,只是为了好玩。发现了一些我不明白的东西 有一个Int32.cs文件,其C代码表示Int32类型。不知怎的,我觉得这很奇怪。C编译器如何编译Int32类型的代码 public struct Int32: IComparable, IFormattable, IConvertible { internal int m_value; // ... } 但这在C#不是违法的吗?如果int只是Int32的别名,则它将无法编译: “struct1”类型的结构
Int32
类型。不知怎的,我觉得这很奇怪。C编译器如何编译Int32
类型的代码
public struct Int32: IComparable, IFormattable, IConvertible {
internal int m_value;
// ...
}
但这在C#不是违法的吗?如果int
只是Int32
的别名,则它将无法编译:
“struct1”类型的结构成员“struct2 field”在结构布局中导致循环
编译器中有什么魔力吗,或者我完全偏离了轨道了吗?
int
是Int32
的别名,但是您正在查看的Int32
结构只是元数据,它不是真正的对象。int m_值
声明可能只是为了给结构提供适当的大小,因为它从来没有在其他地方被引用过(这就是为什么它被允许存在的原因)
换句话说,编译器可以避免这一问题。有一场关于这个话题的讨论
从讨论中,这里引用了所选答案中的一段话,这有助于确定声明的可行性:
虽然类型确实包含一个整数m_值字段,但
字段从未被引用。在每种支护方法中(比较,
ToString等),则使用“this”代替。有可能
m_值字段仅用于强制结构具有
大小合适
我怀疑当编译器看到“int”时,它会将其转换为“a”
参考mscorlib.dll中的System.Int32,稍后解析”,以及
由于它正在构建mscorlib.dll,因此最终会出现循环错误
引用(但不是可能导致问题的引用,因为m_值
从不使用)。如果这一假设是正确的,那么这一技巧将
仅适用于特殊编译器类型
进一步阅读,可以确定结构只是元数据,而不是真正的对象,因此它不受相同的递归定义约束的约束
这在C#不是违法吗?如果“int”是“Int32”的唯一别名,则编译失败,错误为CS0523。编译器中有什么魔力吗
对,;在编译器中故意抑制该错误。如果所讨论的类型是内置类型,则完全跳过循环检查器
通常这种事情是违法的:
struct S { S s; int i; }
在这种情况下,S的大小是未定义的,因为无论S的大小如何,它必须等于自身加上int的大小。没有这样的大小
struct S { S s; }
在这种情况下,我们没有信息来推断S的大小
struct Int32 { Int32 i; }
但是在本例中,编译器提前知道System.Int32
是四个字节,因为它是一种非常特殊的类型
顺便说一句,C#编译器(以及CLR)如何确定一组结构类型何时是循环的细节非常有趣。我会在某个时候写一篇关于这一点的博客文章。我认为目前的答案没有找到真正的问题:“如果
Int32
只是int
的别名,那么Int32类如何使用int
?”这里有一些关于同一个问题的很好的讨论:同意@Tim。这是一个好问题,可能是标题中应该问的问题。jure,我认为安是合适的。内置类型很神奇。它们必须是——否则一路上都是海龟。然而,你的问题的答案非常简短。编译器中是否有特殊情况允许System.Int32
具有类型为System.Int32
的字段,这通常是一个错误?显然:是的。这个问题实际上已经解决了;通常会有一个错误,int的极端特殊情况下不会有错误,因此编译器中必须有一个特殊情况。还有,我想如果m_值被声明为Int32,编译就会失败。关于MSDN的有趣讨论。最后,这确实很重要,但值类型有一些奇怪的源代码:)System.Int32
不是类,而是结构。我认为值得注意的是,m_值实际上在源代码中使用了很多。然而,编译器的IL发射器有一个特殊的规则,它用父对象代替递归valuetype中递归的任何用法。当然,CLR不会加载这样的递归valuetype,内置的除外。Int32是我在.NET源代码下载完成时打开的第一个文件。然后第一句话震惊了我。在.NET源代码中有一行代码不应该存在。经过几分钟的自我怀疑,我得出了结论,你看到的是Int-struct的代码,就像奇点一样,这里不适用标准的物理定律。。所以我关闭了文件:)无论如何,期待着你的博客文章,总是很高兴阅读它们。我认为电子的内容是虚拟光子和虚拟电子-正电子对。(类似地,Int32应该定义为struct Int32{byte byte1;byte byte2;byte byte3;byte byte4;}
我的正电子在哪里,所以我可以将int转换为void![StructLayout(LayoutKind.Auto,Size=4)]struct S{S;}
会有信息来推断S的大小。但是如果没有特殊的语言和编译器支持,它就没有多大用处。@EricLippert先生,你在你提到的博客上写过这篇文章吗?如果是,你能分享它的链接吗?