对值类型和引用类型的理解

【前置知识】

内存中有栈区(stack)和堆区(heap)来存放数据。对值类型和引用类型的区别这个问题而言,我们只需要明白以下两点即可:

  • 在空间大小上,栈<堆
  • 在读取速度大小上,栈>堆

【拓展】内存中的堆和栈到底是什么

【定义】

按照数据在内存中的存储位置,可以将所有数据分为值类型和引用类型两类。

有类数据的规模(即数据量)很小,所以需要的空间也小,其通常存储在栈区,也即栈区存储了这类数据的值,这类数据就叫值类型数据。我们要获取值类型数据的值,只要找到其在栈区中的哪个位置(即地址)即可获得该值。

有类数据的规模(即数据量)很大,所以需要的空间也大,其通常存储在堆区,也即堆区存储了这类数据的值,而在栈区存储了这类数据的引用,这类数据就叫引用类型数据。我们想要获取引用类型数据的值,要先找到数据的引用在栈区的位置,在这个位置获取引用,通过引用找到数据在堆区的位置,获得数据的值。

【C#中预定义的值类型和引用类型】

【前置知识】对数据类型的理解

C#中预定义的值类型数据包括:整型、浮点型、字符型、bool型

C#中预定义的引用类型数据包括:string型、object型(注解:通常而言,字符串可以很长,需要的空间较大,而一般的数需要的空间不大)

C#中的值类型包括:值类型数据、结构struct、枚举enum

C#中的引用类型包括:引用类型数据、数组、类、接口、委托(注解:数组、类可以看做由很多的数据组成的,需要的空间大)

【值类型和引用类型的区别】

【赋值区别】

值类型:把数据的值复制过去

引用类型:把数据的引用复制过去

【内存分配区别】

值类型:只需要栈中单独的一块内存区域用于存储数据的值。

引用类型:需要堆中的一块区域存放数据的值,还需要栈中的一块内存区域存放数据的引用(即地址)

【继承区别】

值类型:继承自System.ValueType,所有的不能被继承

引用类型:继承自Sysyem.Object,有的可以被继承(主要指类和接口)

class Program
    {
        static void Main(string[] args)
        {
            int a = 0;
            int b = 1;
            a = b;//把b的值复制给a
            a = 2;
            Console.WriteLine(a+" "+b);//输出2 1

            string str1 = "abc";
            string str2 = "xyz";
            str1 = str2;//把str2的引用复制给str1
            str1 = "lmn";//在堆中新分配了一块区域存储“lmn”(而不是将str2所指的存储区域的值更改),并把引用给str1,
            Console.WriteLine(str1 + " " +str2);//输出lmn xyz

            int[] A = {1, 2, 3};
            int[] B = {4, 5, 6};
            A = B;
            A[0] = 10;//更改了引用所指向的存储区域中的一个数的数值
            foreach (int temp in A)
            {
                Console.Write(temp + " ");//输出10 5 6
            }
            foreach (int temp in B)
            {
                Console.Write(temp + " ");//输出10 5 6,而不是4 5 6
            }

            Console.ReadKey();
        }
    }

【值类型和引用类型之间的类型转换】

对C#装箱和拆箱的理解

【参考】

[1]《C#本质论5.0》

[2]https://blog.csdn.net/qiaoquan3/article/details/51202926

【相关链接】

表现得像值类型的string类型

值类型和引用类型的嵌套

你可能感兴趣的:(C#,值类型,引用类型)