.NET进阶系列之三:string类型特性小记

(1)string是引用类型:
string是引用类型,这就是说string在堆上保存数据,而在栈中存储的是对象地址,在理解string类型特性时首先需要记住这点。只不过与其它一些引用类型相比,它又有一些比较特殊的特性,比如下面的这些:
 
(2)string是不可变的(immutable):
string的这一特性是指,对于已有的一个string对象,当你修改它时,实际是重新创建了一个符合你要求的string对象。我通过以下的例子进行演示:
static void Main(string[] args)
{
    string x = "should it matter";
    x = x + " ?"//breakpoint (1)
}//breakpoint (2)

F5运行至breakpoint (1)处,在即时窗口中执行以下sos调试命令(关于sos调试扩展,可以参见《VS 2005中Sos调试扩展简介》):
 
!load sos.dll
extension C:"WINDOWS"Microsoft.NET"Framework"v2.0.50727"sos.dll loaded
!clrstack -a
PDB symbol for mscorwks.dll not loaded
OS Thread Id: 0x1508 (5384)
ESP       EIP    
0012f440 012f009f ConsoleApplication1.Program.Main(System.String[])
    PARAMETERS:
        args = 0x0137cdc8
    LOCALS:
        <CLR reg> = 0x0137cdd8
0012f69c 79e7c74b [GCFrame: 0012f69c]
 
F5运行至breakpoint (2)处,重新执行clrstack命令,结果如下。可清楚看到对象x在内存中的地址发生了变化,由原来的0x0137cdd8变成0x0137ce24
 
!clrstack -a
OS Thread Id: 0x1508 (5384)
ESP       EIP    
0012f440 012f00b0 ConsoleApplication1.Program.Main(System.String[])
    PARAMETERS:
        args = 0x0137cdc8
    LOCALS:
        <CLR reg> = 0x0137ce24
0012f69c 79e7c74b [GCFrame: 0012f69c]

(3)string判等:
对于string类型来说,其equals()方法与“==”操作符起到的效果都是一样的,这点可以从“==”操作的反编译代码中可以看出来:
public static bool operator ==(string a, string b)
{
    return Equals(a, b);
}
跟其它引用类型一样,如果你需要判断两个字符串变量的是否引用相等(即指向托管堆上的同一地址),可以使用object.ReferenceEquals()方法。
 
(4)string留用:
static void Main(string[] args)
{
    string x = "should it matter";
    string y = "should it matter";
    if (object.ReferenceEquals(x, y))
    {
        Console.WriteLine("same reference.");
    }
    Console.Read();
}
程序运行的结果是输出了“same reference.”,照理说我声明两个string变量,它们不应该指向相同的托管堆地址啊?!事实上这里涉及到一个所谓的“字符串留用”机制,根据Jeffrey Richter在《框架设计:CLR via C#》中所说,CLR存在一种机制,当它初始化时,它会创建一个内部哈希表,此表中key是字符串,value是对托管堆中的string对象的引用。当定义一个string 时,就会在内部哈希表中检查是否有相匹配的。如果不存在完全相同的字符串,就创建字符串副本,将字符串副本添加到内部哈希表中,并返回这个副本的引用。如果存在完全相同的字符串,就返回对现有字符串的引用。
事实上,我认为该机制有通常情况下有害无益:(1)以上述程序为例,它会导致字符串比较(判等),以便确定是否已存在相同的字符串;(2)它会造成开发人员的一种混乱感觉,因为按照正常逻辑,上述程序中的两个对象不应该是引用相等。可惜在.net framework 2.0及以上版本中,该机制是默认工作的。
关于字符串的留用机制,详细可以看Jeffrey Richter的《框架设计:CLR via C#》,包括其中对string.intern()方法的描述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值