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

时间:2019-12-04 02:34:51

标签: c#

参考源网站上的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;
}

但是我注意到了...

  • boolSystem.Boolean的{​​{3}}。
  • 类型为struct Boolean,这是一个值类型,表示a C# language alias
  • ...但是此代码大概可以编译。
  • 我了解,设置了-nostdlib编译器选项后,您需要提供自己的 essential 类型定义,例如System.StringSystem.Int32,{{1} }-这是唯一的区别。
  • 已发布的源代码不包含其他System.Exception之类的特殊属性。

那么这段代码如何编译?

1 个答案:

答案 0 :(得分: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进行装箱(由于类型擦除或不可能进行优化),您最终会得到类似{{ 1}},将值true装箱。

1

因此,在较高级别的ldc.i4.1 box [mscorlib]System.Boolean bool看来是相同的,并且可以类似地进行优化,在这种特殊情况下,运行时中,{{1的盒装版本和未盒装版本之间的区别}}直接暴露出来。类似地,无法将未装箱的System.Boolean与本来是装箱类型的bool进行比较。 This answer regarding the need for boxing/unboxing在解释原理本身方面更加深入。

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

尽管this question about 'bool' being a type alias for 'System.Boolean'本质上涵盖了一般用例,但在接近运行时实现时,C#的方言变得更像“特定于实现的C#”,可以稍微改变规则。