C# 如果Int32只是int的别名,那么Int32类如何使用int?

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”类型的结构

一直在浏览.NET的源代码,只是为了好玩。发现了一些我不明白的东西

有一个Int32.cs文件,其C代码表示
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先生,你在你提到的博客上写过这篇文章吗?如果是,你能分享它的链接吗?