C#-值类型、引用类型

发布于:2024-11-03 ⋅ 阅读:(115) ⋅ 点赞:(0)

一:值类型、引用类型

1.1 值类型

整型、浮点、bool、char、枚举、结构体

仅需一段内存来存储实际的数据、单独定义时放在栈上

1.2 引用类型

string、数组、类(自定义类、内置的类)

需2段内存

  1. 存放实际数据、位于堆中(因为占得位置比较大)

  2. 存放引用,指向数据在堆中的位置(保存地址)

二:值类型和引用类型的区别

2.1 使用上的区别

值类型:在相互赋值时,把内容拷贝给了对方,它变我不变

引用类型:在相互赋值时,让两者指向同一个值,它变我也变

2.2 为什么有以上区别

两者所存储的内存区域及存储方式不同

值: 栈 → 系统分配,自动回收,小而快

引用:堆 → 手动申请和释放,大而慢

在使用引用类型赋值时,赋值的是引用类型的引用,即地址

值类型数组,数组中直接存储值

引用类型数组,数组中存储的是引用(内存地址)

 new 了 就是在堆中开了新空间,和之前的,没有什么关系了

三:string是特殊引用类型

string是引用类型,但它具备,值类型的特征→它变我不变

string缺点:频繁改变string,会重新赋值,会产生 内存垃圾。

string型数据在赋值时,原数据不变。因为string在赋值时会在堆中重新分配内存空间,并修改栈中存储的地址

3.1 string使用上的缺点
  • 修改会导致频繁的内存分配和垃圾收集

  • 内存分配:每次使用 + 运算符或 Concat 方法连接字符串时,都会分配内存以创建一个新的字符串对象。在循环中进行字符串连接会导致性能问题。

  • 性能开销:对于需要频繁修改字符串内容的场景,使用 string 可能导致不必要的性能开销。例如,在构建一个由多个部分组成的字符串时,每部分的添加都涉及创建一个新对象。

  • 不支持缓冲区操作:string 类型不支持直接操作字符缓冲区,这在需要处理大量文本数据时可能不够高效。

  • 隐式装箱:由于 string 是引用类型,当它被赋值给一个 object 类型变量时,会发生装箱操作,这可能会增加额外的性能开销。

  • 安全性:不可变的 string 对象可以提高安全性,因为它们不能被意外修改。然而,在某些情况下,这可能限制了对字符串的直接操作。

  • 国际化和格式化:在处理国际化应用程序时,string 类型可能不足以处理复杂的文本格式化和文化差异。

  • 编码问题:在处理非ASCII字符时,string 类型默认使用 UTF-16 编码,这在处理大量非ASCII文本时可能导致内存使用增加。

3.2 string的优化替代方案
  1. StringBuilder:频繁的字符串修改或连接操作

  2. 处理大量数据,考虑使用 Span<T>ReadOnlySpan<T> 来避免不必要的内存分配。

  3. 使用 string.IsNullOrEmptystring.IsNullOrWhiteSpace: 在检查空字符串时,使用 string.IsNullOrEmptystring.IsNullOrWhiteSpace 而不是 == null== "" 可以避免不必要的字符串创建。


网站公告

今日签到

点亮在社区的每一天
去签到