C#中的String类型

前两天一个朋友问我,想实现一个轻量级的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           [1object o,
 8           [2] int32 int2,
 9           [3string str,
10           [4object oString,
11           [5string 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), 否则将产生一个新的字串.

posted on 2008-07-05 11:54  沙加  阅读(728)  评论(2编辑  收藏  举报

导航