正在浏览.NET Framework Reference Source的 .NET源代码,只是为了它的乐趣.并找到了一些我不明白的东西.
有一个Int32.cs文件,其中包含Int32类型的C#代码.不知怎的,这对我来说似乎很奇怪.C#编译器如何编译Int32类型的代码?
public struct Int32: IComparable, IFormattable, IConvertible {
internal int m_value;
// ...
}
Run Code Online (Sandbox Code Playgroud)
但这在C#中不是非法的吗?如果int只是别名 Int32,则无法使用错误CS0523进行编译:
'struct1'类型的struct成员'struct2字段'在struct布局中导致循环.
编译器中有一些魔法,还是我完全偏离轨道?
由于structin C#由其成员的位组成,因此您不能拥有T包含任何T字段的值类型:
// Struct member 'T.m_field' of type 'T' causes a cycle in the struct layout
struct T { T m_field; }
Run Code Online (Sandbox Code Playgroud)
我的理解是上述类型的实例永远不能被实例化* - 任何尝试这样做会导致实例化/分配的无限循环(我猜这会导致堆栈溢出?**) - 或者,另外,另一个看待它的方式可能是定义本身没有意义; 也许这是一个弄巧成拙的实体,有点像"这句话是假的".
但奇怪的是,如果你运行这段代码:
BindingFlags privateInstance = BindingFlags.NonPublic | BindingFlags.Instance;
// Give me all the private instance fields of the int type.
FieldInfo[] int32Fields = typeof(int).GetFields(privateInstance);
foreach (FieldInfo field in int32Fields)
{
Console.WriteLine("{0} ({1})", field.Name, field.FieldType);
}
Run Code Online (Sandbox Code Playgroud)
...您将获得以下输出:
m_value (System.Int32)
看来我们正在"骗"到这里***.显然,我的理解是原始类型,如int,double等必须在C#的肠子深跌一些特殊的方法(你不能在系统方面的系统中定义每一个可能的单位来定义......可以吗? -不同的话题, 而不管!); …
在看到double.Nan == double.NaNC#中总是如此虚假之后,我开始好奇如何在引擎盖下实现平等.所以我使用Resharper来反编译Double结构,这是我发现的:
public struct Double : IComparable, IFormattable, IConvertible, IComparable<double>, IEquatable<double>
{
// stuff removed...
public const double NaN = double.NaN;
// more stuff removed...
}
Run Code Online (Sandbox Code Playgroud)
这似乎表明结构Double声明了一个用这个特殊的小写字母定义的常量double,尽管我一直认为这两个是完全同义的.更重要的是,如果我使用小写双精度执行实现,Resharper只需将我滚动到文件顶部的声明.同样地,跳转到小写的实现NaN只是让我在前面的行中进行常量声明!
所以我试图理解这个看似递归的定义.这只是反编译器的人工制品吗?可能是Resharper的限制?或者这个小写的双重实际上是一个完全不同的野兽 - 代表CLR/CTS较低级别的东西?
NaN真的来自哪里?