c# - 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;
}
但我注意到...
bool
是. _ _System.Boolean
- 该类型是
struct Boolean
一个值类型,这意味着它不能将自身包含为一个字段。 - ...但是这段代码可能会编译。
- 我知道,
-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);
}
我相信在上面,表示布尔类型的盒装结构首先进行类型检查,然后将其拆箱并bool
直接比较内部值。与装箱类型(可能是标记指针或具有一些运行时类型信息的实际结构)不同,未装箱类型被视为实际数据。
我在内部相信,如果必须将 bool 装箱以传递为System.Object
(因为类型擦除或无法进行优化),您最终会得到类似于 this 的true
内容1
。
ldc.i4.1
box [mscorlib]System.Boolean
因此,虽然在较高级别上bool
看起来System.Boolean
是相同的并且可以类似地进行优化,但在运行时的这种特殊情况下,盒装和非盒装版本之间的区别bool
直接暴露出来。类似地,bool
无法将未装箱的类型与System.Object
固有的装箱类型进行比较。就解释原理本身而言,有关装箱/拆箱需求的答案更加深入。
在托管语言中,当涉及到一些核心运行时特性时,运行时实现通常需要免除某些规则,这对于 Java 和其他基于 JVM 的语言来说当然是正确的。虽然我也不熟悉 CLR,但我认为这里也适用相同的原则。
虽然这个关于 'bool' 是 'System.Boolean' 的类型别名的问题基本上涵盖了一般用例,但当接近运行时实现时,C# 的方言变得更像“特定于实现的 C#”,这可能会稍微改变规则.
推荐阅读
- python - 没有重叠单词的句子的 Fuzzywuzzy 分数高于那些有一些重叠的句子?
- r - 使用条件将列更改为单独的数据框
- json - 未在 Wikidata 或 DBpedia 上的 Wikipedia 表数据的 JSON,下一步?
- php - MySQL全文搜索修改,任意顺序搜索词
- c# - 将 XML 转换为 JSON 到 c# 对象
- ruby-on-rails - 为 Rails 创建简单的站点密码 - 没有用户名
- javascript - 当我登录并导航到新屏幕时,UI 冻结。一旦我刷新应用程序,屏幕就会工作。知道为什么吗?
- node.js - 如何从angular4组件传递参数来表达API
- c++ - 如何从 begin() 和 end() 中实现 cbegin() 和 cend()?
- date - 日期格式 - COGNOS