博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.Net Discovery 系列之二--string从入门到精通(下)
阅读量:5862 次
发布时间:2019-06-19

本文共 3917 字,大约阅读时间需要 13 分钟。

 前两节我们介绍了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()方法返回的就是这个字段。

本文转自Aicken(李鸣)博客园博客,原文链接:http://www.cnblogs.com/isline/archive/2009/02/04/1383835.html,如需转载请自行联系原作者

你可能感兴趣的文章
CSS3 修改和去除移动端点击事件出现的背景框 (tap-highlight-color)
查看>>
form表单直接传文件
查看>>
集合框架综述
查看>>
解决ReSharper自动删除换行
查看>>
21window_21_Dynamic_library动态库
查看>>
DB2 v9.1 RACF 瞎学笔记
查看>>
根据两点间的经纬度计算距离
查看>>
PHP常用的文件操作函数集锦
查看>>
基于OpenCV的图像几何变换算法
查看>>
学习django各种奇葩错误日志
查看>>
在 Range 对象中,Min (12)必须小于或等于 max (-1)。
查看>>
唯一ID算法之:snowflake(Java版本)
查看>>
1854: [Scoi2010]游戏
查看>>
算法模板——哈希单模板字符串匹配
查看>>
单片机IAP学习
查看>>
Python 学习笔记【05】流程控制
查看>>
jquery text
查看>>
如何通俗易懂地解释卷积?
查看>>
HTTP协议详解
查看>>
Cap07_项目成本管理
查看>>