| 网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 |
![]() |
| Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道 |
接下来我们来逐句地分析这段代码: 中国网管联盟bitsCN.com
| string str1 = "ABCD1234"; string str2 = "ABCD1234"; object.ReferenceEquals(str1, str2)= True; object.ReferenceEquals(str1, "ABCD1234")) = True; |
首先我们创建了两个完全相同的字符串(ABCD1234),并将他们分别赋予了两个字符创变量——str1和str2.然后把它们传给了 object.ReferenceEquals.我们知道object.ReferenceEquals是用于确定两个变量是否具有相同的引用——换句话说,当两个变量引用的是同一块托管推的内存快的时候,返回True,否则返回False.
令我们感到奇怪的是,当我们分别创建的引用类型两个变量——string是引用类型。照理说CLR会在托管堆(Managed Heap)中为它们分配两段内存快,他们不可能具有相同的引用才对,但是为什么object.ReferenceEquals 方法会返回True呢。而对于第二个比较——一个字符串变量和一个和他具有相同内容的字符串("ABCD1234";)直接进行比较,按照我们对CLR内存的分配的一般理解,应该是CLR首先会在托管堆中为这段字符串("ABCD1234")分配内存快,然后把相对应的引用传递给 object.ReferenceEquals方法(由于分配在托管堆的这段字符串并没有被任何变量引用,所以当垃圾回收的时候会被回收掉),所以无论如何也不应该返回True. 中国网管论坛bbs.bitsCN.com
我们先把问题留到最后,接着分析我们的Sample.上面们对字符串变量之间以及变量与字符串之间进行了比较,如果我们对一个字符串变量和一个动态创建的字符串(通过+Operator把两个字符串连接起来)进行比较,结果又会如何呢?我们来看看下面的伪代码演示: 网管u家u.bitsCN.com
| string str3 = "ABCD"; string str4 = "1234"; string str5 = "ABCD" + "1234"; string str6 = "ABCD" + str4; string str7 = str3 + str4; object.ReferenceEquals(str1, str5) = True object.ReferenceEquals(str1, str6) = False object.ReferenceEquals(str1, str7)) = False |
在上面的例子中,我们用三种不同的方式创建了3个字符串变量(str5,str6,str7)——string+string;string+ variable;variable+variable.然后分别和我们已经创建的、和它们具有相同字符串“值”的变量(str1)作比较。同样令我们感到奇怪的是第一个返回True,而后两个则为False.带着这些疑惑我们来看看对于string这一特殊的类型说采用的特殊的使用机制。
网管联盟bitsCN_com
1. System.String虽然是一个引用类型,但是它具有其自身的特殊性。我们最容易想到的是它创建的特殊性——一般的对象在创建的时候需要通过new 关键字调用对应的构造函数来实现;而创建一段string不需要这么做——我们只需要把对应的字符换赋给给对应的字符串变量就可以了。之所以存在着这种差异,是因为他们在创建过程中使用的IL指令时不同的——一般的引用对象的创建是通过newobj这样一个IL指令来实现的,而创建一个字符串变量的IL指令则是ldstr (load string)。(象C#,VB.NET这样的语言毕竟是高级语言,进行了高度的抽象,站在这样的角度分析问题往往不能够看到其实质,所以有时候我们把应该从交底层上面找突破口——比如分析IL,Metadata…); 网管u家u.bitscn@com
网管u家u.bitscn@com
|
0
|
评论加载中…