导读:本期聚焦于唐僧创作的《c#数据类型有哪几种?一文搞懂值类型、引用类型与常用内置类型》,敬请观看详情。C#的数据类型到底怎么划分?本文从值类型与引用类型这两大分支入手,系统讲解整型、浮点型、布尔型、字符型、结构体、枚举等值类型,以及类、接口、数组、字符串、委托等引用类型,并结合内存分配方式分析它们在栈与堆上的存储差异。文章还会介绍类型转换的隐式与显式规则、装箱拆箱带来的性能影响,以及var动态推断和可空类型的实际用法。掌握了这些底层概念后,再面对变量声明、参数传递和方法返回值设计时,就能清楚判断该用什么类型,避免因类型误用导致的编译错误和运行时异常。

C#是一门强类型语言,任何一个变量在使用前都必须明确它的数据类型。类型系统决定了变量占用多少内存、能存什么值、支持哪些运算。初学者往往只记得int、string这些常见写法,却说不清C#到底有几大类类型、它们在内存中如何分配、互相之间怎样转换。这篇文章就把C#的类型体系完整梳理一遍,帮你建立起清晰的知识框架。

c#数据类型有哪几种?一文搞懂值类型、引用类型与常用内置类型

一、C#数据类型的整体分类:值类型与引用类型

C#的数据类型从大的方向上分为两大类:值类型和引用类型。这个划分依据的不是类型的功能,而是变量在内存中的存储方式,理解了这一点,后面很多行为差异就都能解释通了。

值类型直接把数据本身存储在栈上(准确地说,是存储在变量声明的位置)。当你把一个值类型变量赋值给另一个变量时,系统会在内存中完整复制一份数据,两个变量从此互不干扰。而引用类型变量存储的是对象在堆上的地址,赋值时复制的只是这个地址,两个变量指向同一个对象,修改其中一个,另一个也能看到变化。

值类型包括:简单类型(整型、浮点型、布尔型、字符型)、结构体struct、枚举enum,以及可空值类型如int?。引用类型包括:类class、接口interface、数组、字符串string、委托delegate、对象object和动态dynamic。可以简单记为:继承了System.ValueType的都是值类型,其余的基本都是引用类型。

二、常用的值类型详解

整型家族是使用频率最高的值类型。C#提供了多种整数类型,区别在于占用字节数和是否有符号。最常用的是int(32位有符号整数,范围约-21亿到21亿),其次是long(64位)、short(16位)、sbyte(8位有符号)以及对应的无符号版本uintulongushortbyte。选择的原则是够用就好,盲目用long会浪费内存。

浮点类型有三种:float(单精度,约7位有效数字)、double(双精度,约15到16位有效数字)和decimal(高精度十进制类型,28到29位有效数字)。这里有个容易踩坑的地方:float和double采用二进制浮点表示,0.1这样的十进制小数无法精确存储,做金额计算会出现误差。涉及钱的场景务必用decimal,字面量要加m后缀。

float price = 3.14f;        // 单精度,必须加f后缀
double pi = 3.1415926;       // 默认浮点类型
decimal money = 199.99m;     // 金额计算必须用decimal,加m后缀
char letter = 'A';           // 字符类型,单引号,16位Unicode
bool isVip = true;           // 布尔类型,只有true和false
byte age = 25;               // 0到255的无符号小整数

除了这些简单类型,结构体和枚举也是值类型。结构体适合定义轻量的、不可分割的数据,比如DateTimeGuidPoint都是.NET内置的结构体。枚举则用来定义一组命名常量,让代码更具可读性,比如把星期几定义成枚举,比用裸数字0到6清晰得多。

三、常用的引用类型详解

引用类型中用得最多的是stringclass。string虽然写起来像值类型,但它是货真价实的引用类型,只不过具有不可变性——任何对字符串的修改操作都会产生新的字符串对象。频繁拼接字符串时应使用StringBuilder,避免内存浪费。

数组、接口、委托也都属于引用类型。数组一旦创建,长度固定不可变;委托则是对方法的封装,是事件机制的基础。还有一个特殊的object类型,它是所有类型的最终基类,任何值类型赋值给object时会发生装箱操作。

string name = "张三";
string greeting = $"你好, {name}";   // 字符串插值
int[] numbers = new int[] { 1, 2, 3 };  // 数组是引用类型

Person p1 = new Person { Age = 20 };
Person p2 = p1;      // 复制的是引用
p2.Age = 30;         // p1.Age也变成30,因为指向同一个对象

struct PointStruct { public int X; }
PointStruct a = new PointStruct { X = 10 };
PointStruct b = a;   // 值类型,完整复制
b.X = 99;            // a.X仍然是10

引用类型变量默认可以为null,而值类型不能直接等于null。如果希望值类型也能表示空值,比如数据库中一个 nullable 的整数字段,可以使用可空类型int?,编译器会把它处理成Nullable<int>结构。

四、类型转换与装箱拆箱

类型之间的转换分隐式和显式两种。隐式转换由编译器自动完成,方向是从小范围到大范围,安全不丢数据,比如int转long、int转double。显式转换需要强制转换语法,从大范围到小范围,可能丢失精度或溢出,需要开发者自己承担风险。

装箱和拆箱是值类型与引用类型之间的桥梁。装箱指把值类型包装成堆上的object对象,拆箱则是反向提取。这个过程涉及内存分配和数据复制,性能开销不小,在循环中频繁装箱会明显拖慢程序。典型的高频场景是把值类型放进非泛型集合(如ArrayList)里,用泛型集合List<int>替代就能彻底避免装箱。

int num = 100;
object boxed = num;          // 装箱:值类型转到堆上
int back = (int)boxed;       // 拆箱:必须显式转换,类型必须完全匹配

double d = 3.9;
int truncated = (int)d;      // 显式转换,结果为3,直接截断小数

long big = 1000000L;
int overflow = checked((int)big);  // checked可开启溢出检查

另外补充一点:var关键字并不是一种新类型,它只是让编译器根据右侧表达式推断出实际类型,推断完成后类型就固定了,仍然属于强类型范畴。合理使用var可以简化冗长的泛型声明,但过度使用会降低代码可读性。

总结一下,C#的数据类型可以先用值类型和引用类型这条主线串起来,再往下细分简单类型、结构体、枚举和类、接口、数组、字符串、委托。判断标准始终是内存分配方式:值类型存数据本身,引用类型存地址。把存储方式、转换规则和装箱机制这三块搞明白,C#的类型系统就算真正掌握了。

C#数据类型值类型引用类型修改时间:2026-09-15 22:00:38

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260915/57526.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。