前两节我们介绍了string的两个基本特性,如果你觉得你已经比较全面的了解了string,那么就来看看这第3、4两节吧。

  三.有趣的比较操作 
  在第一节与第二节中,我们分别介绍了字符串的恒定性与与驻留性,如果这位同学友觉得完全掌握了以上内容,那么就在第三节中检验一下自己的学习成果吧!

  以下10段简单的代码将通过值比较与地址引用比较,来说明前两节讲到的内容,大家也可以通过这些代码来检测一下自己对string的了解程度。

  代码一:
    string a = "str_1";
    string b = "str_1";
    Response.Write(a.Equals(b));
    Response.Write(ReferenceEquals(a,b));

    输出:True (Equals比较字符串对象的值)
          True (ReferenceEquals比较字符串对象的引用,由于字符串驻留机制,a与b的引用相同)

  代码二:
            string a = "str_1str_2";
            string b = "str_1";
            string c = "str_2";
            string d = b + c;
            Response.Write(a.Equals(d));
    Response.Write(ReferenceEquals(a, d));

    输出:True(Equals比较字符串对象的值)
          False(ReferenceEquals比较字符串对象的引用,由于变量d的值为变量连接的结果,字符串驻留机制无效)

  代码三:
    string a = "str_1str_2";
    string b = "str_1" + "str_2";
    Response.Write(a.Equals(b));
    Response.Write(ReferenceEquals(a, b));

    输出:True(Equals比较字符串对象的值)
          True (ReferenceEquals比较字符串对象的引用,由于变量b的值为常量连接的结果,字符串驻留机制有效。如果变量b的值由“常量+变量”的方式得出,则字符串驻留无效)

  代码四:
    string a = "str_1";
    string b = String.Copy(a);
    Response.Write(a.Equals(b));
    Response.Write(ReferenceEquals(a, b));

    输出:True(Equals比较字符串对象的值)
          False (ReferenceEquals比较字符串对象的引用,Copy操作产生了新的string对象)

  代码五:
    string a = "str_1";
    string b = String.Copy(a);
    b = String.Intern(b);
    Response.Write(a.Equals(b));
    Response.Write(ReferenceEquals(a, b));

    输出:True(Equals比较字符串对象的值)
          True (ReferenceEquals比较字符串对象的引用,String.Intern实现了字符串驻留)

  代码六:
    string a = "str_1";
    string b = String.Copy(a);
    string c = "str_1";
    Response.Write((object)a == (object)b);
    Response.Write((object)a == (object)c);

    输出:False (“==”在两边为引用类型时,则比较引用的地址,所以a与b为    不同引用)
          True (ReferenceEquals比较字符串对象的引用,a与c由于字符串驻留机制,引用相同)

  代码七:
    string a = "str_1";
    string c = "str_1";
    Response.Write(a == c);

    输出:True
  刚才我们提到过,“==”在两边为引用类型时,则比较引用的地址;如果是值类型时则需要比较引用和值。string为引用类型,那么上面的代码是比较了变量a与c的地址还是地址和值呢?答案是:比较了地址和值!因为在string类型比较的时候,“==”已经被重载为“Equals”了,所以,虽然你在用“==”比较两个引用类型,但实际上是在用“Equals”比较它们的地址和值!(先比较地址,地址不等再比较值)

  代码八:
    string a = "a";
    string b = new string('a', 1);
    Response.Write(a.Equals(b));
    Response.Write(ReferenceEquals(a, b));

    输出:True (Equals比较值,a与b的值相同)
          False (ReferenceEquals比较字符串对象的引用)

  代码九:
    string a = "a";
    string b = new string('a', 1);
    Response.Write(a.Equals(string.Intern(b)));
    Response.Write(ReferenceEquals(a, string.Intern(b)));
    输出:True (Equals比较值,无论是否Intern都会相同)
          True (ReferenceEquals比较字符串对象的引用,Intern已经将b驻留至字符串池内)

  代码十:
    string a = "str";
    string b = "str_2".Substring(0,3);
    Response.Write(a.Equals(b));
    Response.Write(ReferenceEquals(a, b));
    输出:True (Equals比较值,a与c的值相同)
          False (ReferenceEquals比较字符串对象的引用,Substring操作产生了新的字符串对象)
      此段代码产生了3个string对象,是哪3个呢?如果你不明白,还是从头再看一遍吧!

  四.艺海拾贝
  这一节将主要给大家介绍一些string的常见问题。
  1.“string = ”与“new stirng()”的区别
    string test = "a";
    string test = new string('a', 1);

  以上两行代码的效果是一样的,它们的区别在于加载”a”的时间不同:第一行的“a”是一个常量,在编译期就已经被放在一个叫做常量池的地方了,常量池通常装载一些在编译期被确定下来的数据,例如类、接口等等;而第二行是运行时CLR在堆中生成的值为“a”的字符串对象,所以后者没有字符串驻留。
  2. string 与 String的区别
  String的大名叫做System.String,在编译为IL代码时,string和System.String会生成完全相同的代码:(ps:long和System.Int64,float和System.Single等也有此特性)
  C#代码:
    string str_test = "test";
           System.String Str_test = "test";
  IL码:
      // 代码大小       14 (0xe)
      .maxstack  1
      .locals init ([0] string str_test,
               [1] string Str_test)
      IL_0000:  nop
      IL_0001:  ldstr      "test"
      IL_0006:  stloc.0
      IL_0007:  ldstr      "test"
      IL_000c:  stloc.1
      IL_000d:  ret
    所以,二者的区别并不在于底层,而是在于string是类似于int的基元类型;System. String是框架类库(FCL)的基本类型,二者之间有直接的对应关系。
  3.StringBuilder
  StringBuilder提供了高效创建字符串的方法,由StringBuilder表示的字符串是可变的(非恒定的),在需要多处使用“+”连接字符串变量的时候,推荐使用StringBuilder来完成,最后调用其ToString()方法输出。当调用了StringBuilder的ToString()方法之后,StringBuilder将返回其内部维护的一个字符串字段引用,如再次修改StringBuilder,它将会创建一个新的字符串,这时被修改的是新的字符串,原来已经返回的字符串才不会发生改变。
    StringBuilder有两个比较重要的内部字段,大家需要掌握:
    m_MaxCapacity:StringBuilder的最大容量,它规定了最多可以放置到        m_StringValue的字符个数,默认值为Int32.MaxValue。m_MaxCapacity一旦被指定就不能再更改。
    m_StringValue:StringBuilder维护的一个字符数组串,实际上可以理解为一个字符串。StringBuilder重写的Tostring()方法返回的就是这个字段。

    讲到这里,你已经掌握了string的大部分秘密,怎么样,你对string应该有全新的认识了吧!

转自:http://www.cnblogs.com/isline/archive/2009/02/04/1383835.html

.Net Discovery 系列之二--string从入门到精通(下)的更多相关文章

  1. Python基本语法[二],python入门到精通[四]

    在上一篇博客Python基本语法,python入门到精通[二]已经为大家简单介绍了一下python的基本语法,上一篇博客的基本语法只是一个预览版的,目的是让大家对python的基本语法有个大概的了解. ...

  2. .Net Discovery 系列之一--string从入门到精通(上)

    string是一种很特殊的数据类型,它既是基元类型又是引用类型,在编译以及运行时,.Net都对它做了一些优化工作,正式这些优化工作有时会迷惑编程人员,使string看起来难以琢磨,这篇文章分上下两章, ...

  3. OPEN(SAP) UI5 学习入门系列之二: 最佳实践练习(下)

    上期我们完成了一个简单的主从页面,但是页面是静态的,不能交互,功能也很简单,只有一个销售订单的列表. 我们今天就一鼓作气把代码全都写完,由于本次的代码量较大,所以只对重点代码部分进行讲解. 具体每个文 ...

  4. 深入浅出Mybatis系列(二)---Mybatis入门

    一.Mybatis环境搭建及简单实例 1. 新建web项目, 添加依赖包:mybatis包.数据库驱动包(我使用的是mysql).日志包(我使用的是log4j), 由于我的是maven项目, 那么添加 ...

  5. BI商业智能培训系列——(二)SSIS入门

    简介: SSIS,Microsoft SQL Server Integration Services.Integration意为"整合"."一体化".上篇博客中 ...

  6. Python基本语法[二],python入门到精通[四] (转)

    写在前面 python你不去认识它,可能没什么,一旦你认识了它,你就会爱上它 回到顶部 v正文开始:Python基本语法 1.定义常量: 之所以上篇博客介绍了定义变量没有一起介绍定义常量,是因为Pyt ...

  7. Jmeter(二十) - 从入门到精通 - JMeter监听器 -下篇(详解教程)

    1.简介 监听器用来监听及显示JMeter取样器测试结果,能够以树.表及图形形式显示测试结果,也可以以文件方式保存测试结果,JMeter测试结果文件格式多样,比如XML格式.CSV格式.默认情况下,测 ...

  8. Jmeter(二十一) - 从入门到精通 - JMeter断言 - 上篇(详解教程)

    1.简介 最近由于宏哥在搭建自己的个人博客可能更新的有点慢.断言组件用来对服务器的响应数据做验证,常用的断言是响应断言,其支持正则表达式.虽然我们的通过响应断言能够完成绝大多数的结果验证工作,但是JM ...

  9. Jmeter(二十三) - 从入门到精通 - JMeter函数 - 上篇(详解教程)

    1.简介 在性能测试中为了真实模拟用户请求,往往我们需要让提交的表单内容每次都发生变化,这个过程叫做参数化.JMeter配置元件与前置处理器都能帮助我们进行参数化,但是都有局限性,为了帮助我们能够更好 ...

随机推荐

  1. spring事务详解(二)实例

    在Spring中,事务有两种实现方式: 编程式事务管理: 编程式事务管理使用底层源码可实现更细粒度的事务控制.spring推荐使用TransactionTemplate,典型的模板模式. 申明式事务管 ...

  2. CVTE笔试题

    一.题目 给定一个数组a[N],我们希望构造数组b [N],其中b[j]=a[0]*a[1]…a[N-1] / a[j],在构造过程中,不允许使用除法: 要求O(1)空间复杂度和O(n)的时间复杂度: ...

  3. laravel 打印sql语句

    public function getCurrencyOrder($user_id=70,$pid=252,$register=['register:first']) { DB::connection ...

  4. Python学习笔记:算法的重要性

    今日看了一个基础的教程<8分钟学会一个算法>,偶然间看到一个很简单的例子,仅当记录一下. 题目:已知a+b+c=1000,且a^2+b^2=c^2,求a,b,c的所有自然数解? #### ...

  5. Django Celery定时任务和时间设置

    1.Celery加入定时任务 Celery除了可以异步执行任务之外,还可以定时执行任务.在实例代码的基础上写个测试方法: #coding:utf- from celery.task.schedules ...

  6. 自己动手破解rar密码-ruby脚本实现

    破解密码,上策是社工的方式,下策则是暴力破解了.这里使用暴力破解,字典文件放在txt中:通过调用winrar的相关参数进行操作.经过测试,当字典中密码为100个时,破解耗时8秒(个人配置:i5-321 ...

  7. Java编程的逻辑 (55) - 容器类总结

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  8. .NetCore 结合微服务项目设计总结下实践心得

    以下内容全是在项目中的体验,个人理解心得 起源 2017年7月开始接触.NetCore,当时还是因为Idr4的原因,之前的项目都是用的Idr3做,后面接触到Idr4后,决定以后所有项目都使用.NetC ...

  9. docker commit 制作镜像

    docker commit -m="commit jdk" --author="gutianlangyu" ae56f6cad215 gutianlangyu/ ...

  10. mysql xtrabackup工具备份

    一.注意事项 建议用xtrabackup备份时采用全备或增量备份的方式,楼主也尝试过单库备份,但是都以备份后恢复到已经存在数据库的mysqldata目录下后部分库会出幺蛾子而告终,建议使用mysqld ...