值类型与参考类型的实例化和初始化

int number = new int();

问题:

  1. 对于引用类型, new运算符通过在堆上分配内存来创建该类型的实例,然后通过调用类型的构造函数对其进行初始化。 如上所示,您可以对值类型执行相同操作。 对我来说,上面的行意味着调用构造函数int()以使用值初始化数字 。 我已经读过int是一个指向struct System.Int32的关键字。 因此,在Visual Studio中,我导航到结构Int32。 瞧,没有构造函数存在。 如果没有构造函数,这个预定义类型究竟是如何初始化为0的?

  2. 与上面相关,Int32结构中是否有一个存储值的字段?

  3. 对于自定义结构和类,我都可以使用new关键字创建新实例,而实际上不包含构造函数的结构或类。 在这种情况下,是否在struct / class包含的所有字段中都没有进行初始化? 唯一的事情就是在堆/堆上为值/引用类型分配内存?

  4. 最后,对于值类型,实例化和初始化不需要新的关键字。 这究竟是如何在较低级别上工作的? 假设我们做int number = 5; 。 它以某种方式转换为int a = new int(); a = 5; ? 如果是这样,怎么样?

太感谢了!

没有[ System.Int32 ]构造函数存在。

所有值类型都有一个默认构造函数 :

每个值类型都有一个隐式默认构造函数,用于初始化该类型的默认值。

(报价结束)

与上面相关,Int32 struct中是否有一个存储值的字段?

是的,它确实:

 [Serializable] [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] [System.Runtime.InteropServices.ComVisible(true)] public struct Int32 : IComparable, IFormattable, IConvertible , IComparable, IEquatable , IArithmetic { internal int m_value; // <<== Here it is public const int MaxValue = 0x7fffffff; public const int MinValue = unchecked((int)0x80000000); ... } 

对于自定义结构和类,我都可以使用new关键字创建新实例,而实际上不包含构造函数的结构或类。

这不完全正确:与struct不同,并非所有类都有隐式默认构造函数; 如果定义一个带参数的构造函数,编译器将从类中删除默认构造函数。

在这种情况下,是否在struct / class包含的所有字段中都没有进行初始化?

未显式初始化的所有字段都将设置为其默认值。

假设我们做int number = 5; 。 它以某种方式转换为int a = new int(); a = 5; int a = new int(); a = 5;

int是内置类型。 编译器知道如何为它生成IL。 int的类型被“烘焙”到编译器为赋值生成的CIL中:

 .locals init ([0] int32 a) ldc.i4.s 5 stloc.0 

第一行对应于int a的声明,有或没有new 。 最后两行执行赋值:将值5加载到寄存器中,并将其存储在局部变量a (索引为零)中。

  1. 即使未定义构造函数,编译器也会生成初始化值的默认构造函数。 话虽如此,我们不应该依赖默认构造函数来初始化。 我认为如果未明确定义默认构造函数MyObject()和复制构造函数MyObject(MyObject second),则会自动创建。

  2. 我没有亲自查看Int32结构,但它应该有一个保存值的成员。

  3. 如上所述,当未定义默认构造函数时,会自动创建它们,以便完成一些初始化。 话虽如此,依靠自动创建的构造函数进行初始化并不是一个好习惯。

  4. 原始类型不需要也不能使用new关键字(除非在创建数组时)。 当你使用new关键字时,似乎int被“转换”为Int32,这是一个类,而不是一个原始的。 所以,int number = 5就是这样。 int a = new int(5)被翻译成int a =(int)new Int32(5)这称为拳击。 某些操作/集合不能直接使用基本类型,因此当基元用于此类情况时,编译器会自动封装基元类型。 如果不需要,则不需要将它们装箱但是将它们用作原始的,即不要新建它们。