技术开发 频道

C#中的String类型


【IT168技术文档】

  想实现一个轻量级的Dictionary<string,object>, 俺告诉他使用 System.Collections.Specialized.HybridDictionay, 它可以根据无素的数量自动选择内部的数据存储结构, 应该说是一个比较理想的选择, 后来又谈到, 如果在里面存储 <string,string>会不会引发装拆箱操作,因为string是值类型的, string在.net中是一个比较特殊的类型,它表现出来是值类型,但是准确的讲它应该是"内置的引用类型", 因此对于上面的操作不会引发装拆箱的操作. 为了验证这个说法写了一段程序: 反汇编结果如下:
1.method private hidebysig static void Main(string[] args) cil managed 2{ 3 .entrypoint 4 // Code size 127 (0x7f) 5 .maxstack 2 6 .locals init ([0] int32 integer, 7 [1] object o, 8 [2] int32 int2, 9 [3] string str, 10 [4] object oString, 11 [5] string str2) 12 IL_0000: nop 13 IL_0001: ldc.i4 0x3e7 14 IL_0006: stloc.0 15 IL_0007: ldstr "Origin integer value is : " 16 IL_000c: ldloca.s integer 17 IL_000e: call instance string [mscorlib]System.Int32::ToString() 18 IL_0013: call string [mscorlib]System.String::Concat(string, 19 string) 20 IL_0018: call void [mscorlib]System.Console::WriteLine(string) 21 IL_001d: nop 22 IL_001e: ldloc.0 23 IL_001f: box [mscorlib]System.Int32 24 IL_0024: stloc.1 25 IL_0025: ldloc.1 26 IL_0026: call int32 [mscorlib]System.Convert::ToInt32(object) 27 IL_002b: stloc.2 28 IL_002c: ldstr "The unbox interger value is : " 29 IL_0031: ldloca.s int2 30 IL_0033: call instance string [mscorlib]System.Int32::ToString() 31 IL_0038: call string [mscorlib]System.String::Concat(string, 32 string) 33 IL_003d: call void [mscorlib]System.Console::WriteLine(string) 34 IL_0042: nop 35 IL_0043: ldstr "Hello world!" 36 IL_0048: stloc.3 37 IL_0049: ldstr "Orgine string value is :" 38 IL_004e: ldloc.3 39 IL_004f: call string [mscorlib]System.String::Concat(string, 40 string) 41 IL_0054: call void [mscorlib]System.Console::WriteLine(string) 42 IL_0059: nop 43 IL_005a: ldloc.3 44 IL_005b: stloc.s oString 45 IL_005d: ldloc.s oString 46 IL_005f: callvirt instance string [mscorlib]System.Object::ToString() 47 IL_0064: stloc.s str2 48 IL_0066: ldstr "Unbox string value is : " 49 IL_006b: ldloc.s str2 50 IL_006d: call string [mscorlib]System.String::Concat(string, 51 string) 52 IL_0072: call void [mscorlib]System.Console::WriteLine(string) 53 IL_0077: nop 54 IL_0078: call string [mscorlib]System.Console::ReadLine() 55 IL_007d: pop 56 IL_007e: ret 57} // end of method Program::Main源程序: static void Main(string[] args) { int integer = 999; Console.WriteLine("Origin integer value is : " + integer.ToString()); object o = (object)integer; int int2 = Convert.ToInt32(o); Console.WriteLine("The unbox interger value is : " + int2.ToString()); string str = "Hello world!"; Console.WriteLine("Orgine string value is :" + str); object oString = (object)str; string str2 = oString.ToString(); Console.WriteLine("Unbox string value is : " + str2); Console.ReadLine(); }
  注意到在反编出来的代码中的23行执行了装箱操作,但是对于后面的字符串转为Object确没有进行box.

  另外, 由于一个字串在.net中一旦被创建出来就不可更改,可以认为CLR在内存维护了一个字符串的字典, 对于字符串的更改会在这个字典中查找是否已经存在,否则就再创建一新的字串. 因此于对这样的操作: Console.Write(str1 + str2)最好写成 Console.Write(str1), Console.Write(str2), 否则将产生一个新的字串.
0
相关文章