参考源网站上的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
是System.Boolean
的{{3}}。struct Boolean
,这是一个值类型,表示a C# language alias。-nostdlib
编译器选项后,您需要提供自己的 essential 类型定义,例如System.String
,System.Int32
,{{1} }-这是唯一的区别。System.Exception
之类的特殊属性。那么这段代码如何编译?
答案 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#”,可以稍微改变规则。