C# Int32: m_value

本文关键字:value Int32 | 更新日期: 2023-09-27 18:26:34

在阅读了一些关于C#中Int32结构的内容后,我意识到intInt32是同义的。在Int32结构体的源代码中,有一个internal int m_value字段。

如果我的知识是正确的,那么我们分配给int变量的值将存储在m_value中(我是对的吗?)。但我的疑问是,当我们给出int i = 7;时,值是如何存储在m_value中的。

我在Int32结构源代码中也没有看到任何隐式运算符,因此值可以存储在m_value中。

有人能帮我吗?

C# Int32: m_value

C#中的

int表示与CIL中的int32相同的东西,后者是一个4字节的基元,通常被视为有符号数。(尽管CIL可以在没有强制转换的情况下对其执行无符号运算)。

它是最底层的构建块之一,我们可以从中创建更复杂的结构和类。

但就其本身而言,它并没有定义任何方法

同时,System.Int32看起来非常像一个封装int/int32的结构,并且确实提供了一些方法。

让我们这样考虑吧;让我们思考一下,在一个没有intSystem.Int32:别名的世界里会是什么样子

在这种假设的情况下,只有当我们将其视为一种特殊的"boxed int"类型,在需要时从int创建System.Int32,并在需要时再次提取int时,我们才能使用System.Int32提供的方法。

因此,如果没有混叠来做(3).CompareTo(2),我们将不得不做:

new System.Int32{m_value = 3}.CompareTo(2)

但是考虑CCD_ 23的存储器内表示是4个字节,而CCD_。如果我们没有一个强大的类型系统来禁止将一种类型视为另一种类型,我们就可以随时将一种视为其他类型。

现在,C#不允许我们这样做。例如,我们不能做:

public struct MyInt32
{
  private int _value;
}
/* … */
MyInt32 = 3;

我们需要添加一个将被调用的强制转换方法,否则C#将拒绝这样处理它。

但CIL没有这样的规则。它可以随时将一种类型视为另一种与布局兼容的类型。因此(3).CompareTo(2)的IL是:

ldc.i4.3 // Push the 32-bit integer 3 on the stack.
ldc.i4.2 // Push the 32-bit integer 2 on the stack.
call instance int32 [mscorlib]System.Int32::CompareTo(int32)

最后的调用只是假设3System.Int32并调用它

这违反了C#类型安全的规则,但这些规则不是CIL的规则。C#编译器也不必遵循它强制执行的所有规则。

因此,不需要在m_value中放入任何内容,我们只需说"哦,那里的四个字节,它们是System.Int32m_value字段",就可以神奇地完成了。(如果你知道C或C++,请考虑如果你有两个具有等效成员的结构,并将指向其中一个类型的指针强制转换为void*,然后再返回到另一个类型。这是一种糟糕的做法,IIRC是未定义的,而不是有保证的,但低级别代码可以做这类事情)。

就是混叠的工作原理。Net语言的编译器特殊情况下,我们需要在基元上调用一个方法来执行C#代码本身不允许的类型强制。

同样,它对值类型不能包含其自身类型的字段这一事实进行了特殊处理,并允许System.Int32具有int字段,尽管通常不允许struct S { public S value; }

这就是语言的工作原理,伙计!

在状态中

int i = 7;

正在创建一个Int32变量。(即int i部分)。但是,您正在为其分配7。C#(以及许多其他语言)中的7被称为文字。这意味着7已经是Int32的一个实例!它是这样的:

假设你有一个类

public class ClassA {
    public int i;
}

以及ClassA:的一个实例

ClassA obj = new ClassA ();
obj.i = 1;

然后你这样做:

ClassA a = obj;

你说,"我在ClassA中没有看到任何隐式运算符,所以值可以存储在i中。"

但是obj已经是一个合法的对象了!就像7一样。

在阅读核心框架的源代码时,很难理解发生了什么。

"当我们给出int i=7;"时,值如何存储在m_value中

首先,当C#编译器看到int时,它只是假装你说的是System.Int32(*)。类似地,当它看到7时,它会说"啊哈!这是一个整数。我会把它存储在System.Int32中"。因此,它创建变量i(正确类型),并使用它创建的值对其进行初始化。

(*)这意味着来源http://referencesource.microsoft.com/#mscorlib/system/int32.cs,225942具有:

public struct Int32 : *various bases*
{
    internal Int32 m_value;

这有点令人困惑(通常是不合法的)。