- #1 : 在. Net Framework 中, 字符总是表示成 16 位 Unicode 的代码 #2 :String 和 string 其实是一样的只是表现形式上不同 #3 :string 类型被视为基元类型, 也就是编译器允许在源代码中直接使用字面值表示字符串, 编译器将这些字符串放到模块的元数据中, 并在运行时加载和引用它们.
- static void Main(string[] args)
- {
- string s = "2";
- Console.WriteLine(s);
- Console.ReadLine();
- }
il 查看如下:
- .method private hidebysig static void Main(string[] args) cil managed
- {
- .entrypoint
- // 代码大小 21 (0x15)
- .maxstack 1
- .locals init ([0] string s)
- IL_0000: nop
- IL_0001: ldstr "2"
- IL_0006: stloc.0
- IL_0007: ldloc.0
- IL_0008: call void [mscorlib]System.Console::WriteLine(string)
- IL_000d: nop
- IL_000e: call string [mscorlib]System.Console::ReadLine()
- IL_0013: pop
- IL_0014: ret
- } // end of method Program::Main
IL 指令构造对象的新实例是 newobj 上面的 IL 中并没有 newobj IL 为 ldstr 也就是 CLR 用一种特殊的方式构造了 string 对象 #4:string 中的 + 操作符的实质
- static void Main(string[] args)
- {
- string s = "2"+"3";
- Console.WriteLine(s);
- Console.ReadLine();
- }
如果所有的字符串是字面值, 则编译器在编译时连接它们, 最终只有一个字符串 "23", 对于非字面值的字符串使用 + 操作符, 连接则在运行时进行, 对于运行时连接不要使用 + 操作符, 这样会在堆上创建多个字符串对象, 堆是需要垃圾回收的, 对性能有影响, 对于这种应使用 stringbuilder#5: 字符串是不可变的 string 对象一旦创建便不能更改
- static void Main(string[] args)
- {
- string s = "2";
- Console.WriteLine(s);
- ChangeStr(s);
- Console.ReadLine();
- }
- private static void ChangeStr(string s)
- {
- s = "1";
- }
- 2
- 2
IL 代码:
- .method private hidebysig static void ChangeStr(string s) cil managed
- {
- .method private hidebysig static void Main(string[] args) cil managed
- {
- .entrypoint
- // 代码大小 35 (0x23)
- .maxstack 1
- .locals init ([0] string s)
- IL_0000: nop
- IL_0001: ldstr "2"
- IL_0006: stloc.0
- IL_0007: ldloc.0
- IL_0008: call void [mscorlib]System.Console::WriteLine(string)
- IL_000d: nop
- IL_000e: ldloc.0
- IL_000f: call void ConsoleApp2.Program::ChangeStr(string)
- IL_0014: nop
- IL_0015: ldloc.0
- IL_0016: call void [mscorlib]System.Console::WriteLine(string)
- IL_001b: nop
- IL_001c: call string [mscorlib]System.Console::ReadLine()
- IL_0021: pop
- IL_0022: ret
- } // end of method Program::Main
- // 代码大小 9 (0x9)
- .maxstack 8
- IL_0000: nop
- IL_0001: ldstr "1"
- IL_0006: starg.s s
- IL_0008: ret
- } // end of method Program::ChangeStr
虽然 string 是个对象存放在堆上, 但它并不像其他的应用对象一样对它的改变直接反应, 通过上面的代码我们的可以发现 CLR 为每个字符串都创建了对象, 这样做的好处: 字符串不可变, 则操作或访问字符串时不会发生线程同步问题, CLR 可通过共享多个完全一致的 string 内容, 这样减少了系统中字符串数量 从而节省内存.#6 : 安全字符串对于一些敏感数据我们可以使用 System.Security.SecureString 该类实现了 IDisposable 使用完后可以进行销毁, 防止数据的泄露.
来源: https://www.cnblogs.com/starxing/p/9563256.html