mscorlib的`System.Boolean`如何避免结构布局循环?


10

System.Boolean参考源网站上的的源代码指出的实例struct Boolean仅包含一个bool字段private bool m_value

https://referencesource.microsoft.com/#mscorlib/system/boolean.cs,f1b135ff6c380b37

namespace System {

    using System;
    using System.Globalization;
    using System.Diagnostics.Contracts;

    [Serializable]
    [System.Runtime.InteropServices.ComVisible(true)]
    public struct Boolean : IComparable, IConvertible
#if GENERICS_WORK
        , IComparable<Boolean>,  IEquatable<Boolean>
#endif
    {
      private bool m_value;

      internal const int True = 1; 
      internal const int False = 0; 

      internal const String TrueLiteral  = "True";
      internal const String FalseLiteral = "False";

      public static readonly String TrueString  = TrueLiteral;
      public static readonly String FalseString = FalseLiteral;
}

但我注意到...

  • bool一个C#语言的别名System.Boolean
  • 类型是struct Boolean值类型,这意味着它不能包含自己作为字段
  • ...但是此代码大概可以编译。
  • 据我所知,当-nostdlib编译器选项设置您需要提供自己的必不可少的类型定义一样System.StringSystem.Int32System.Exception-这是唯一的区别。
  • 已发布的源代码不包含其他特殊属性,例如[MethodImpl( MethodImplOptions.InternalCall )]

那么该代码如何编译?


1
这是一个体面的证明,常见的“这是一个别名”假设是一个破碎的心理模型。 bool是C#语言中的关键字。编译器和运行时都具有很多关于类型的内置知识,不需要System.Boolean的帮助。mscorlib中原始值类型的声明与该类型的框式表示形式匹配。
汉斯·帕桑

Answers:


3

简短答案:这是一种特殊情况,与类型拳击及其基础表示有关。这些类型是编译器众所周知的,因此与常规类型相比,运行时和编译器/ JIT优化器的核心部分对它们的处理略有不同。


由于这是深埋在运行时实现中的,因此我认为语言规范不会涉及特定的运行时实现细节。我不确定这是否足够令人满意,但是我认为在这种特殊情况下,该bool类型保持未装箱状态,因此作为原始值类型存在于结构中。

装箱和拆箱值类型的语义是故意不透明的,以使使用该语言更加容易。在这种情况下,Boolean结构本身似乎依赖于特定于实现的装箱规则来实现实际的语义,例如:

  // Determines whether two Boolean objects are equal.
  public override bool Equals (Object obj) {
    //If it's not a boolean, we're definitely not equal
    if (!(obj is Boolean)) {
      return false;
    }

    return (m_value==((Boolean)obj).m_value);
  }

我相信,在上面的内容中,首先对表示布尔类型的框式结构进行了类型检查,然后对它进行了拆箱并bool直接比较了内部值。与装箱的类型(可能是带标记的指针或带有某些运行时类型信息的实际结构)不同,未装箱的类型被视为实际数据。

我内部认为,如果必须将布尔值装箱以作为System.Object伪装(由于类型擦除或无法进行优化的原因)而被装箱,则最终会得到一些与之true相对应的值1

ldc.i4.1
box        [mscorlib]System.Boolean

因此,尽管在高级别boolSystem.Boolean似乎是相同的,并且可类似地优化,在运行中该特定情况下,的装箱和取消装箱版本之间的差别bool直接暴露。相似地,bool无法将未装箱的System.Object与其本身是装箱的类型进行比较。关于解释装箱/拆箱的需要的答案在解释原理本身方面更加深入。

在托管语言中,当涉及到某些核心运行时功能时,通常需要使运行时实现免除某些规则,这对于Java和其他基于JVM的语言当然是正确的。虽然我也不熟悉CLR,但我认为这里也适用相同的原则。

尽管有关“布尔”是“ System.Boolean”的类型别名的问题基本上涵盖了一般用例,但在接近运行时实现时,C#的方言更像“特定于实现的C#”,这可能会稍微改变规则。


为了您的见解,我对此表示赞成-但我不能将其标记为已接受的答案,因为它不具权威性,对不起:(
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.