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

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

有一个Int32.cs文件,其中包含用于Int32类型的C#代码。 不知何故,这对我来说似乎很陌生。 C#编译器如何编译Int32类型的代码?

public struct Int32: IComparable, IFormattable, IConvertible {
    internal int m_value;

    // ... 
}

但在C#中这不是非法的吗? 如果int只是Int32的别名,则它将无法使用错误CS0523进行编译:

类型'struct1'的结构成员'struct2字段'会在结构布局中产生一个循环。

编译器中是否有一些神奇的东西,还是我完全偏离了轨道?


在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)如何确定何时一组结构类型是循环的细节非常有趣。 我会尽力在某个时候写一篇博客文章。


intInt32的别名,但您正在查看的Int32结构仅仅是元数据,它不是一个真正的对象。 int m_value声明可能只是为了给结构赋予适当的大小,因为它实际上从来没有被其他地方引用(这就是为什么它被允许在那里)。

所以,换句话说,编译器可以避免这个问题。 有关MSDN论坛中的主题的讨论。

从讨论中,下面是所选答案的一段引文,它有助于确定宣言的可行性:

虽然类型包含整数m_value字段是确实的,但该字段永远不会被引用。 在每个支持方法(CompareTo,ToString等)中,都使用“this”代替。 可能只有m_value字段才能强制结构具有适当的大小。

我怀疑,当编译器看到“int”时,它会将其转换为“mscorlib.dll中的System.Int32的引用,稍后解决”,并且由于它正在构建mscorlib.dll,因此它会以循环引用结束但没有一个可以造成问题,因为m_value从不使用)。 如果这个假设是正确的,那么这个技巧只适用于特殊的编译器类型。

进一步阅读,可以确定该结构仅仅是元数据,而不是一个真实的对象,所以它不受同样的递归定义限制。

链接地址: http://www.djcxy.com/p/21049.html

上一篇: If Int32 is just an alias for int, how can the Int32 class use an int?

下一篇: Is an int a 64