C#Int32:m_value

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

如果我的知识是正确的,我们分配给int变量的值存储在m_value (我是否正确?)。 但我怀疑当我们给int i = 7;时,值是如何存储在m_value int i = 7;

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

谁能帮我这个?

C#中的int表示与CIL中的int32相同的东西,这是一个4字节的原语,通常被视为有符号数。 (虽然CIL可以在没有强制转换的情况下对其执行无符号操作)。

它是最低级别的构建块之一,我们可以继续创建更复杂的结构和类。

但同样,它没有定义任何方法。

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

让我们考虑一下; 让我们考虑在没有使用System.Int32别名的情况下它会是什么样子:

在这个假设的情况下,我们只允许使用System.Int32提供的方法,如果我们将其视为一个特殊的“boxed int”类型,在我们需要时从int创建一个System.Int32 ,并再次提取int当我们需要的时候。

所以,没有别名做(3).CompareTo(2)我们必须这样做:

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

但是考虑到int的内存表示是4个字节,而System.Int32的内存中表示是相同的4个字节。 如果我们没有强大的类型系统禁止将一种类型视为另一种类型,我们可以随时将其中一种视为另一种类型。

现在,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#type-safety的规则,但这些规则不是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一个实例了! 就像这样:

假设你有一个class级

 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中int i=7;

首先,当C#编译器看到int ,它只是假装你说System.Int32而不是(*)。 类似地,当它看到7 ,它会说“啊哈!这是一个整数字面值。我将它存储在System.Int32 ”。 然后它创建变量i (正确类型),并使用它创建的值初始化它。

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

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

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