C#有三种类型,其中指针类型微软不建议使用,所以不介绍了。
值类型和应用类型,其实很好区分和解释。我就用一段代码一个图说明清楚
* 自定义类型:结构体
代码如下:
/// <summary> /// 结构体 /// </summary> public struct People { public string Name { get; set; } public int Age { get; set; } public void Write() { Console.WriteLine($"值类型 Name={Name} ,Age={Age}"); } } /// <summary> /// 引用类 /// </summary> public class PeopleClass { public string Name { get; set; } public int Age { get; set; } public void Write() { Console.WriteLine($"引用类型 Name={Name} ,Age={Age}"); } }
static void Main(string[] args) { Console.WriteLine("值类型输出开始================="); People p = new People(); p.Name = "tom"; p.Age = 18; p.Write(); People pp = p; pp.Write(); Console.WriteLine("pp改变一下值================="); pp.Name = "jack"; pp.Age = 20; pp.Write(); p.Write(); Console.WriteLine("值类型输出结束================="); Console.WriteLine("引用类型输出开始================="); PeopleClass pc=new PeopleClass(); pc.Name = "tom"; pc.Age = 18; pc.Write(); PeopleClass pcref = pc; pcref.Write(); Console.WriteLine("pcref改变一下值================="); pcref.Name = "jack"; pcref.Age = 20; pcref.Write(); pc.Write(); Console.WriteLine("引用类型输出结束================="); Console.ReadLine(); }
输出结果:
值类型输出开始=================
值类型 Name=tom ,Age=18
值类型 Name=tom ,Age=18
pp改变一下值=================
值类型 Name=jack ,Age=20
值类型 Name=tom ,Age=18
值类型输出结束=================
引用类型输出开始=================
引用类型 Name=tom ,Age=18
引用类型 Name=tom ,Age=18
pcref改变一下值=================
引用类型 Name=jack ,Age=20
引用类型 Name=jack ,Age=20
引用类型输出结束=================
最终结论:
可以看出由于类是需要开辟堆区空间,变量是指向堆区的引用。所以引用类型赋值不会改变堆区的引用。而值类型是直接在栈区开辟空间。
关于堆区和栈区, 比较抽象 。我最近在复读《深入理解计算机系统》,里面讲到了计算机存储原理可以解惑。
在字段作用域的影响下,栈区会被新值覆盖。而堆区会自动被GC处理。
值类型:高效,缺点作为数据的载体。没有多态。
引用类型:需要被GC,实现丰富。