C# 中 `string str = null` 与 `string str = ““` 的深度解析


在 C# 编程中,字符串处理是最基础也是最常见的操作之一。理解 null 和空字符串( "")的区别对于编写健壮、无错误的代码至关重要。本文将全面剖析这两种字符串初始化的区别,包括内存结构、行为差异、使用场景以及最佳实践。

一、概念本质区别

1.1 内存表示图解

无引用
引用有效但Length=0
«Representation»
NullString
+Value: null
+Memory: 不占用堆空间
+Stack: 存储引用(4/8字节)
«Representation»
EmptyString
+Value: ""
+Memory: 占用堆空间
+Length: 0
+Stack: 存储引用(4/8字节)
«Structure»
StringObject
+SyncBlockIndex: int
+TypeHandle: IntPtr
+Length: int
+FirstChar: char

1.2 核心区别说明

  • string str = null:

    • 表示引用不指向任何对象
    • 变量在栈上存在,但不指向堆中的任何字符串对象
    • 任何尝试访问其方法/属性都会抛出 NullReferenceException
  • string str = "":

    • 表示引用指向一个长度为零的字符串对象
    • 在堆上分配了完整的字符串对象结构
    • 可以安全调用所有字符串方法和属性

二、技术细节对比

2.1 行为差异对比表

特性 string str = null string str = ""
引用有效性 无效(不指向任何对象) 有效(指向空字符串对象)
内存分配 仅栈上引用(4/8字节) 栈引用+堆对象(16+字节)
方法调用 抛出 NullReferenceException 正常执行
与空字符串比较 str == "" 返回 false str == "" 返回 true
String.IsNullOrEmpty 返回 true 返回 true
String.IsNullOrWhiteSpace 返回 true 返回 true
序列化表现 通常序列化为 null 序列化为 “” 或空元素
模式匹配 str is null 为 true str is "" 为 true

2.2 内存结构对比表

内存区域 string str = null string str = ""
栈空间 存储一个 null 引用(4/8字节) 存储一个有效引用(4/8字节)
堆空间 无分配 分配至少 16 字节的对象头
对象头 不存在 SyncBlock + TypeHandle
字符串长度字段 不存在 值为 0
字符数组 不存在 存在但为空

三、代码示例与行为演示

3.1 基础行为示例

string nullStr = null;
string emptyStr = "";

// 长度获取尝试
try
{