zoukankan      html  css  js  c++  java
  • C# String详解

    .Net 框架程序设计(修订版)中有这样一段描述:String类型直接继承自Object,这使得它成为一个引用类型,也就是说线程上的堆栈上不会驻留有任何字符串。(译注:注意这里的“直接继承”。直接继承自Object的类型一定是引用类型,因为所有的值类型都继承自System.ValueType。值得指出的是System.ValueType却是一个引用类型。)。

          

    代码一:


    string str1 = "string"; string str2 = "string"; Console.WriteLine(string.ReferenceEquals(str1, str2));

    既然String类型是引用类型,那么代码一输出的应该是False,然而事实上代码一输出时的是True。这是因为当CLR初始化的时,它会创建一个内部的散列表,Key为字符串,Value为指向托管堆中字符串对象的引用。当构造str1时,先会去散列表中查询是否存在”string”字符串,如果不存在那么会在托管堆中构造一个新的String对象,然后将”string”字符串和指向该对象的引用添加到散列表中,当构造str2时,由于散列表中存在Key为”string”的引用,于是将Value值赋值给str2,那么str1和str2引用的是同一个String对象,代码一自然就返回True了

    代码二:


    static void Main(string[] args) { string str = "string"; Change(str); Console.WriteLine(str); } static void Change(string str) { str = "Changed"; }

    方法传递的参数是原内容的拷贝,其过程如果用图可表示为:

    语句str=”Changed”之前

    diyblPic

    语句str=”Changed”之后

    diyblPic

    这样可以看到原来String对象并未改变str=”Changed”只是创建一个新的String对象(其它引用类型是改变内存地址1指向的值),因此这个方法的参数需要加上ref或者out修饰符。因此这里也可以得出字符串具有恒等性,也就是说一个字符串一旦被创建,我们就不能再将其变长、变短、或者改变其中的任何字符。

    代码三:


    string str1 = "string"; string str2 = "system." + "string"; string str3 = "system." + str1; Console.WriteLine(string.Equals(str3, str2)); Console.WriteLine(string.ReferenceEquals(str2, str3)); string str4 = "system.string"; Console.WriteLine(string.Equals(str4, str2)); Console.WriteLine(string.ReferenceEquals(str2, str4));

    根据代码一和二的分析,代码三的输出结果为:True True True True,然而事实却不是这样,正确的结果为:True False True True。这是因为动态创建的字符串不会去查询散列表,而是直接在托管堆中创建新的String对象,如语句string str3 = “syetem.”+str1,因此用string.ReferenceEquals来比较str2和str3会返回False,而用string.ReferenceEquals来比较str2和str4会返回True。当然可以将str3字符串手动加入到散列表中,并返回引用:str3 = string.Intern(str3),这样用string.ReferenceEquals来比较str2和str3会返回True,至于string.Equals都返回True的原因是String重写了Equals方法,内部会先检查两个引用是否指向同一个对象,如果是返回True,不是则再比较各个字符。

    引自:http://www.diybl.com/course/4_webprogram/asp.net/netjs/20091107/181566.html

    用发现的眼光来看这个互联网,总有我们立脚的地方!——北纬28.33
  • 相关阅读:
    命令拷屏之网络工具
    PHP 设计模式 笔记与总结(1)命名空间 与 类的自动载入
    Java实现 计蒜客 1251 仙岛求药
    Java实现 计蒜客 1251 仙岛求药
    Java实现 计蒜客 1251 仙岛求药
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 LeetCode 143 重排链表
    Java实现 LeetCode 143 重排链表
  • 原文地址:https://www.cnblogs.com/aisini/p/1717632.html
Copyright © 2011-2022 走看看