值类型与参考类型的实例化和初始化
int number = new int();
问题:
对于引用类型,new运算符通过在堆上分配内存来创建该类型的实例,然后通过调用该类型的构造函数来初始化它。 如上所示,您可以对值类型执行相同的操作。 对我来说,上面的这一行意味着构造函数int()被调用来初始化数值。 我读过int是一个指向struct System.Int32的关键字。 因此,在Visual Studio中,我导航到结构Int32。 瞧,没有构造函数存在。 没有构造函数,这个预定义类型究竟是如何初始化为0的呢?
与上述相关,Int32结构中是否存在一个存储该值的字段?
对于自定义结构和类,我都可以用new关键字创建新实例,而不用实际包含构造函数的结构或类。 在这种情况下,是否在struct / class包含的所有字段都没有进行初始化? 发生的唯一情况是内存是在堆栈/堆上为值/引用类型分配的吗?
最后,对于值类型,实例化和初始化不需要新的关键字。 这在更低的层面上究竟如何工作? 说我们做int数= 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<Int32>, IEquatable<Int32>
, IArithmetic<Int32> {
internal int m_value; // <<== Here it is
public const int MaxValue = 0x7fffffff;
public const int MinValue = unchecked((int)0x80000000);
...
}
对于自定义结构和类,我都可以用new关键字创建新实例,而不用实际包含构造函数的结构或类。
这不完全正确:与struct
s不同,并不是所有的类都有一个隐式的默认构造函数; 如果您定义了一个接受参数的构造函数,编译器会从您的类中移除默认的构造函数。
在这种情况下,是否在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
(在索引零处)。
即使未定义构造函数,编译器也会生成初始化该值的默认构造函数。 话虽如此,我们不应该依赖默认构造函数来初始化。 如果未明确定义,我认为默认构造函数MyObject()和复制构造函数MyObject(MyObject second)会自动创建。
我没有亲自看过Int32结构,但它应该有一个保存值的成员。
如前所述,如果未定义默认构造函数,则会自动创建它们以便完成一些初始化。 话虽如此,依靠自动创建的构造函数来执行初始化并不是一个好习惯。
原始类型不需要也不能使用新的关键字(除非在创建数组时)。 当你使用new关键字时,它看起来像int被“转换”为类Int32,而不是原语。 所以,int number = 5就是这样。 int a = new int(5)被转换为int a =(int)new Int32(5)这被称为装箱。 某些操作/集合不能直接使用基本类型,因此当基本类型用于这种情况时,编译器会自动填充基本类型。 如果不需要,不需要将它们装箱,而是将它们用作原始的,即不要新建它们。
上一篇: Instantiation and Initialization of Value Types vs. Reference Types