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

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)这被称为装箱。 某些操作/集合不能直接使用基本类型,因此当基本类型用于这种情况时,编译器会自动填充基本类型。 如果不需要,不需要将它们装箱,而是将它们用作原始的,即不要新建它们。

  • 链接地址: http://www.djcxy.com/p/85319.html

    上一篇: Instantiation and Initialization of Value Types vs. Reference Types

    下一篇: Internal Source Code Documentation