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;
}
Run Code Online (Sandbox Code Playgroud)
但我注意到...
bool是一个C#语言的别名为System.Boolean。struct Booleanwhich 是值类型,这意味着它不能将自身包含为字段。-nostdlib编译器选项时,您需要提供自己的基本类型定义,例如System.String, System.Int32, System.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);
}
Run Code Online (Sandbox Code Playgroud)
我相信上面的内容,首先对表示布尔类型的装箱结构进行类型检查,然后将其拆箱并bool直接比较内部值。与装箱类型(可能是标记指针或具有某些运行时类型信息的实际结构)不同,未装箱类型被视为实际数据。
我相信在内部,如果必须将 bool 装箱才能传递System.Object(由于类型擦除或无法进行优化),您最终会得到与此类似的内容,其中truebox 为 value 1。
ldc.i4.1
box [mscorlib]System.Boolean
Run Code Online (Sandbox Code Playgroud)
因此,虽然在较高级别上看起来是相同的bool并且System.Boolean可以类似地进行优化,但在运行时的这种特殊情况下,装箱版本和未装箱版本之间的区别bool直接暴露出来。类似地,未装箱的类型不能与本质上是装箱的类型bool进行比较。这个关于装箱/拆箱需求的答案在解释原理本身方面更加深入。System.Object
在托管语言中,当涉及到某些核心运行时功能时,运行时实现通常需要免除某些规则,对于 Java 和其他基于 JVM 的语言来说当然也是如此。虽然我也不熟悉 CLR,但我认为这里也适用同样的原则。
虽然关于“bool”是“System.Boolean”的类型别名的问题本质上涵盖了一般用例,但当接近运行时实现时,C# 的方言变得更像“特定于实现的 C#”,这可能会稍微改变规则。