C# · 12月 20, 2021

[读书笔记]C#学习笔记八:StringBuilder与String详解及参数传递问题剖析

<p style=”background: gray; color: #ffffff; font-size: 18pt;”>前言

对于C#中的参数传递,根据参数的类型可以分为四类:

值类型参数的按值传递引用类型参数的按值传递值类型参数的按引用传递引用类型参数的按引用传递

Main( addNum = Add( addnum = addnum + }

,为了证明这点,看看下面的代码和运行结果就明白了:

Main( Console.WriteLine( addNum = Add( addnum = addnum + }

运行结果是: 从结果中可以看出。具体的分析请看下面的图:

1.2引用类型参数的按值传递当传递的参数是引用类型的时候,传递和操作的是指向对象的引用(看到这里,有些朋友会觉得此时不是传递引用吗?怎么还是按值传递了?对于这个疑惑,此时确实是按值传递,此时传递的对象的地址,传递地址本身也是传递这个地址的值,所以此时仍然是按值传递的),此时方法的操作就会改变原来的对象。代码如下:

Main( RefClass refClass = addnumRef.addnum += addnum= }

运行结果为:

1.3string引用类型参数的按值传递的特殊情况对于String类型同样是引用类型,然而对于string类型的按值传递时,此时引用类型的按值传递却不会修改实参的值,可能很多朋友对于这点很困惑,下面具体看看下面的代码:

Main( str = ChangeStr( oldStr = }

运行结果为:

是因为string的“不变性”,所以在被调用方法中执行 oldStr=”New string”代码时,此时并不会直接修改oldStr中的”old string”值为”New string”,因为string类型是不变的,不可修改的,此时内存会重新分配一块内存,然后把这块内存中的值修改为 “New string”,然后把内存中地址赋值给oldStr变量,所以此时str仍然指向 “old string”字符,而oldStr却改变了指向,它最后指向了 “New string”字符串。所以运行结果才会像上面这样,下面内存分布图可以帮助你更形象地理解文字表述:

1.4按引用传递

不管是值类型还是引用类型,我们都可以使用ref 或out关键字来实现参数的按引用传递,然而按引用进行传递的时候,需要注意下面两点:

方法的定义和方法调用都必须同时显式使用ref或out,否则会出现编译错误

CLR允许通过out 或ref参数来实现方法重载。如:

CLR 允许out或ref参数来实现方法重载 Add( Add(

按引用传递可以解决由于值传递时改变引用副本而不影响引用本身的问题,此时传递的是引用的引用(也就是地址的地址),而不是引用的拷贝(副本)。下面就具体看看按引用传递的代码:

Main( 按引用传递 Console.WriteLine( num = refStr = ChangeByValue( changeByRef( 按引用传递 ChangeByValue( numValue = changeByRef( numRef = }

运行结果为:按引用传递的情况

对于按值传递,不管是值类型还是引用类型的按值传递,都是传递实参的一个拷贝,只是值类型时,此时传递的是实参实例的一个拷贝(也就是值类型值的一个拷贝),而引用类型时,此时传递的实参引用的副本。对于按引用传递,传递的都是参数地址,也就是实例的指针。

StringBuilder vs String.concat():

(1)string

打开Reflector,找到string类

找到Concat方法,我们这里以Concat为例:

下面我们在看下FillStringChecked(dest,str0)的实现方式:

(2)stringBuilder

看这个类的话,还是看一下它的源代码,以Append吧,从下面这个截图中看出来几个有意思的地方。

原来StringBuilder里面维护的是一个m_ChunkChars的字符数组。

如果当前的字符串的length2的时候看到的是刚才string类中经典的wstrcpy用法,而

      这个时候ptr指向的是chunkChars[chunkLength]的首地址,而不像string中申请新的内存空间,所以从这里看,比string大大的节省

    了内存空间。

重谈字符串连接性能上:http://blog.zhaojie.me/2009/11/string-concat-perf-1-benchmark.html重谈字符串连接性能中:http://blog.zhaojie.me/2009/12/string-concat-perf-2-stringbuilder-implementations.html重谈字符串连接性能下:http://blog.zhaojie.me/2009/12/string-concat-perf-3-profiling-analysis.htmlPS:好了,到了这里@Learning Hard的 的读书笔记就分享完了. 后面开始自己学Asp.Net(以前学的是java,接触最多的是jsp,到了公司开始做.Net),对于Asp.Net还不是太了解,希望用一段时间可以掌握这个. 另外空闲时间还在读这本书,很不错的一本书,需要慢慢去消化.