C#Int32:m_value
在C#中读了一下有关Int32
结构的内容之后,我意识到int
和Int32
是同义词。 在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)
最后的调用假定3
是System.Int32
并调用它。
这打破了C#type-safety的规则,但这些规则不是CIL的规则。 C#编译器也不必遵循它强制执行的所有规则。
所以没有必要把任何东西放到m_value
,我们只是说“那里的那四个字节,它们是System.Int32
的m_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;
……这有点令人困惑(通常不合法)。