mscorlib的"System.Boolean"如何避免结构布局周期?



参考源网站上的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的 C# 语言别名。
  • 类型是struct Boolean,这是一个值类型,这意味着它不能将自身作为字段包含。
  • 。然而,这段代码大概可以编译。
  • 我知道,当设置-nostdlib编译器选项时,您需要提供自己的基本类型定义,例如System.StringSystem.Int32System.Exception- 这是唯一的区别。
  • 发布的源代码不包含其他特殊属性,如[MethodImpl( MethodImplOptions.InternalCall )]

那么这段代码是如何编译的呢?

简短回答:这是一个特殊情况,与类型拳击及其底层表示有关。这些类型是编译器众所周知的,因此与常规类型相比,运行时的核心部分和编译器/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也不熟悉,但我认为这里同样适用同样的原则。

虽然关于"bool"是"System.Boolean"的类型别名的问题基本上涵盖了一般用例,但当接近运行时实现时,C# 的方言变得更像"特定于实现的 C#",这可能会稍微改变规则。

最新更新