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