日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

[你必须知道的.NET]第十二回:参数之惑---传递的艺术(下)

發(fā)布時(shí)間:2025/7/25 asp.net 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [你必须知道的.NET]第十二回:参数之惑---传递的艺术(下) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文將介紹以下內(nèi)容:

  • 按值傳遞與按引用傳遞深論
  • ref和out比較?
  • 參數(shù)應(yīng)用淺析?

?

接上篇繼續(xù),『第十一回:參數(shù)之惑---傳遞的藝術(shù)(上)

4.2 引用類(lèi)型參數(shù)的按值傳遞

當(dāng)傳遞的參數(shù)為引用類(lèi)型時(shí),傳遞和操作的是指向?qū)ο蟮囊?#xff0c;這意味著方法操作可以改變?cè)瓉?lái)的對(duì)象,但是值得思考的是該引用或者說(shuō)指針本身還是按值傳遞的。因此,我們?cè)诖吮仨毲宄牧私庖韵聝蓚€(gè)最根本的問(wèn)題:

  • 引用類(lèi)型參數(shù)的按值傳遞和按引用傳遞的區(qū)別?
  • string類(lèi)型作為特殊的引用類(lèi)型,在按值傳遞時(shí)表現(xiàn)的特殊性又如何解釋?

首先,我們從基本的理解入手來(lái)了解引用類(lèi)型參數(shù)按值傳遞的本質(zhì)所在,簡(jiǎn)單的說(shuō)對(duì)象作為參數(shù)傳遞時(shí),執(zhí)行的是對(duì)對(duì)象地址的拷貝,操作的是該拷貝地址。這在本質(zhì)上和值類(lèi)型參數(shù)按值傳遞是相同的,都是按值傳遞。不同的是值類(lèi)型的“值”為類(lèi)型實(shí)例,而引用類(lèi)型的“值”為引用地址。因此,如果參數(shù)為引用類(lèi)型時(shí),在調(diào)用方代碼中,可以改變引用的指向, 從而使得原對(duì)象的指向發(fā)生改變,如例所示:?

引用類(lèi)型參數(shù)的按值傳遞
//?FileName????:?Anytao.net.My_Must_net
//?Description?:?The?.NET?what?you?should?know?of?arguments.?
//?Release??????:?2007/07/01?1.0

//?Copyright???:?(C)2007?Anytao.com??http://www.anytao.com

using?System;

namespace?Anytao.net.My_Must_net
{
????class?Args
????{
????????public?static?void?Main()
????????{
????????????ArgsByRef?abf?=?new?ArgsByRef();
????????????AddRef(abf);
????????????Console.WriteLine(abf.i);
????????}

????????private?static?void?AddRef(ArgsByRef?abf)
????????{
????????????abf.i?=?20;
????????????Console.WriteLine(abf.i);
????????}

????}

????class?ArgsByRef
????{
????????public?int?i?=?10;
????}
}


因此,我們進(jìn)一步可以總結(jié)為:按值傳遞的實(shí)質(zhì)的是傳遞值,不同的是這個(gè)值在值類(lèi)型和引用類(lèi)型的表現(xiàn)是不同的:參數(shù)為值類(lèi)型時(shí),“值”為實(shí)例本身,因此傳遞的是實(shí)例拷貝,不會(huì)對(duì)原來(lái)的實(shí)例產(chǎn)生影響;參數(shù)為引用類(lèi)型時(shí),“值”為對(duì)象引用,因此傳遞的是引用地址拷貝,會(huì)改變?cè)瓉?lái)對(duì)象的引用指向,這是二者在統(tǒng)一概念上的表現(xiàn)區(qū)別,理解了本質(zhì)也就抓住了根源。關(guān)于值類(lèi)型和引用類(lèi)型的概念可以參考《第八回:品味類(lèi)型---值類(lèi)型與引用類(lèi)型(上)-內(nèi)存有理》《第九回:品味類(lèi)型---值類(lèi)型與引用類(lèi)型(中)-規(guī)則無(wú)邊》《第十回:品味類(lèi)型---值類(lèi)型與引用類(lèi)型(下)-應(yīng)用征途》,相信可以通過(guò)對(duì)系列中的值類(lèi)型與引用類(lèi)型的3篇的理解,加深對(duì)參數(shù)傳遞之惑的昭雪。

了解了引用類(lèi)型參數(shù)按值傳遞的實(shí)質(zhì),我們有必要再引入另一個(gè)參數(shù)傳遞的概念,那就是:按引用傳遞,通常稱為引用參數(shù)。這二者的本質(zhì)區(qū)別可以小結(jié)為:

  • 引用類(lèi)型參數(shù)的按值傳遞,傳遞的是參數(shù)本身的值,也就是上面提到的對(duì)象的引用;
  • 按引用傳遞,傳遞的不是參數(shù)本身的值,而是參數(shù)的地址。如果參數(shù)為值類(lèi)型,則傳遞的是該值類(lèi)型的地址;如果參數(shù)為引用類(lèi)型,則傳遞的是對(duì)象引用的地址。

關(guān)于引用參數(shù)的詳細(xì)概念,我們馬上就展開(kāi)來(lái)討論,不過(guò)還是先分析一下string類(lèi)型的特殊性,究竟特殊在哪里?

關(guān)于string的討論,在本人拙作《第九回:品味類(lèi)型---值類(lèi)型與引用類(lèi)型(中)-規(guī)則無(wú)邊》已經(jīng)有了討論,也就是開(kāi)篇陳述的本文成文的歷史,所以在上述分析的基礎(chǔ)上,我認(rèn)為應(yīng)該更能對(duì)第九回的問(wèn)題,做以更正。

string本身為引用類(lèi)型,因此從本文的分析中可知,對(duì)于形如

static void ShowInfo(string aStr){...}

的傳遞形式,可以清楚的知道這是按值傳遞,也就是本文總結(jié)的引用類(lèi)型參數(shù)的按值傳遞。因此,傳遞的是aStr對(duì)象的值,也就是aStr引用指針。接下來(lái)我們看看下面的示例來(lái)分析,為什么string類(lèi)型在傳遞時(shí)表現(xiàn)出特殊性及其產(chǎn)生的原因?

//?FileName????:?Anytao.net.My_Must_net
//?Description?:?The?.NET?what?you?should?know?of?arguments.?
//?Release??????:?2007/07/05?1.0

//?Copyright???:?(C)2007?Anytao.com??http://www.anytao.com
using?System;

namespace?Anytao.net.My_Must_net
{
????class?how2str
????{
????????static?void?Main()
????????{
????????????string?str?=?"Old?String";
????????????ChangeStr(str);
????????????Console.WriteLine(str);
????????}

????????static?void?ChangeStr(string?aStr)
????????{
????????????aStr?=?"Changing?String";
????????????Console.WriteLine(aStr);
????????}
????}
}

下面對(duì)上述示例的執(zhí)行過(guò)程簡(jiǎn)要分析一下:首先,string str = "Old String"產(chǎn)生了一個(gè)新的string對(duì)象,如圖表示:

?

然后執(zhí)行ChangeStr(aStr),也就是進(jìn)行引用類(lèi)型參數(shù)的按值傳遞,我們強(qiáng)調(diào)說(shuō)這里傳遞的是引用類(lèi)型的引用值,也就是地址指針;然后調(diào)用ChangeStr方法,過(guò)程aStr = "Changing String"完成了以下的操作,先在新的一個(gè)地址生成一個(gè)string對(duì)象,該新對(duì)象的值為"Changing String",引用地址為0x06賦給參數(shù)aStr,因此會(huì)改變aStr的指向,但是并沒(méi)有改變?cè)瓉?lái)方法外str的引用地址,執(zhí)行過(guò)程可以表示為:

?

因此執(zhí)行結(jié)果就可想而知,我們從分析過(guò)程就可以發(fā)現(xiàn)string作為引用類(lèi)型,在按值傳遞過(guò)程中和其他引用類(lèi)型是一樣的。如果需要完成ChangeStr()調(diào)用后,改變?cè)瓉?lái)str的值,就必須使用ref或者out修飾符,按照按引用傳遞的方式來(lái)進(jìn)行就可以了,屆時(shí)aStr = "Changing String"改變的是str的引用,也就改變了str的指向,具體的分析希望大家通過(guò)接下來(lái)的按引用傳遞的揭密之后,可以自行分析。

4.3 按引用傳遞之ref和out

不管是值類(lèi)型還是引用類(lèi)型,按引用傳遞必須以ref或者out關(guān)鍵字來(lái)修飾,其規(guī)則是:

  • 方法定義和方法調(diào)用必須同時(shí)顯示的使用ref或者out,否則將導(dǎo)致編譯錯(cuò)誤;
  • CRL允許通過(guò)out或者ref參數(shù)來(lái)重載方法,例如:?
//?FileName????:?Anytao.net.My_Must_net
//?Description?:?The?.NET?what?you?should?know?of?arguments.?
//?Release??????:?2007/07/03?1.0

//?Copyright???:?(C)2007?Anytao.com??http://www.anytao.com

using?System;
namespace?Anytao.net.My_Must_net._11_Args
{
????class?TestRefAndOut
????{
????????static?void?ShowInfo(string?str)
????????{
????????????Console.WriteLine(str);
????????}
????????static?void?ShowInfo(ref?string?str)
????????{
????????????Console.WriteLine(str);
????????}
????}
}

當(dāng)然,按引用傳遞時(shí),不管參數(shù)是值類(lèi)型還是引用類(lèi)型,在本質(zhì)上也是相同的,這就是:ref和out關(guān)鍵字將告訴編譯器,方法傳遞的是參數(shù)地址,而不是參數(shù)本身。理解了這一點(diǎn)也就抓住了按引用傳遞的本質(zhì),因此根據(jù)這一本質(zhì)結(jié)論我們可以得出以下更明白的說(shuō)法,這就是:

  • 不管參數(shù)本身是值類(lèi)型還是引用類(lèi)型,按引用傳遞時(shí),傳遞的是參數(shù)的地址,也就是實(shí)例的指針。
  • 如果參數(shù)是值類(lèi)型,則按引用傳遞時(shí),傳遞的是值類(lèi)型變量的引用,因此在效果上類(lèi)似于引用類(lèi)型參數(shù)的按值傳遞方式,其實(shí)質(zhì)可以分析為:值類(lèi)型的按引用傳遞方式,實(shí)現(xiàn)的是對(duì)值類(lèi)型參數(shù)實(shí)例的直接操作,方法調(diào)用方為該實(shí)例分配內(nèi)存,而被調(diào)用方法操作該內(nèi)存,也就是值類(lèi)型的地址;而引用類(lèi)型參數(shù)的按值傳遞方式,實(shí)現(xiàn)的是對(duì)引用類(lèi)型的“值”引用指針的操作。例如:??
//?FileName????:?Anytao.net.My_Must_net
//?Description?:?The?.NET?what?you?should?know?of?arguments.?
//?Release??????:?2007/07/06?1.0

//?Copyright???:?(C)2007?Anytao.com??http://www.anytao.com
using?System;

namespace?Anytao.net.My_Must_net
{
????class?TestArgs
????{
????????static?void?Main(string[]?args)
????????{
????????????int?i?=?100;
????????????string?str?=?"One";
????????????ChangeByValue(ref?i);
????????????ChangeByRef(ref?str);
????????????Console.WriteLine(i);
????????????Console.WriteLine(str);
????????}

????????static?void?ChangeByValue(ref?int?iVlaue)
????????{
????????????iVlaue?=?200;
????????}

????????static?void?ChangeByRef(ref?string?sValue)
????????{
????????????sValue?=?"One?more.";
????????}
????}
}

如果參數(shù)是引用類(lèi)型,則按引用傳遞時(shí),傳遞的是引用的引用而不是引用本身,類(lèi)似于指針的指針概念。示例只需將上述string傳遞示例中的ChangeStr加上ref修飾即可。?

下面我們?cè)龠M(jìn)一步對(duì)ref和out的區(qū)別做以交代,就基本闡述清楚了按引用傳遞的精要所在,可以總結(jié)為:

  • 相同點(diǎn):從CRL角度來(lái)說(shuō),ref和out都是指示編譯器傳遞實(shí)例指針,在表現(xiàn)行為上是相同的。最能證明的示例是,CRL允許通過(guò)ref和out來(lái)實(shí)現(xiàn)方法重載,但是又不允許通過(guò)區(qū)分ref和out來(lái)實(shí)現(xiàn)方法重載,因此從編譯角度來(lái)看,不管是ref還是out,編譯之后的代碼是完全相同的。例如:
//?FileName????:?Anytao.net.My_Must_net
//?Description?:?The?.NET?what?you?should?know?of?arguments.?
//?Release??????:?2007/07/03?1.0

//?Copyright???:?(C)2007?Anytao.com??http://www.anytao.com

using?System;
namespace?Anytao.net.My_Must_net._11_Args
{
????class?TestRefAndOut
????{
????????static?void?ShowInfo(string?str)
????????{
????????????Console.WriteLine(str);
????????}
????????static?void?ShowInfo(ref?string?str)
????????{
????????????Console.WriteLine(str);
????????}
????????static?void?ShowInfo(out?string?str)
????????{
????????????str?=?"Hello,?anytao.";
????????????Console.WriteLine(str);
????????}
????}
}

編譯器將提示: “ShowInfo”不能定義僅在 ref 和 out 上有差別的重載方法。?

  • 不同點(diǎn):使用的機(jī)制不同。ref要求傳遞之前的參數(shù)必須首先顯示初始化,而out不需要。也就是說(shuō),使用ref的參數(shù)必須是一個(gè)實(shí)際的對(duì)象,而不能指向null;而使用out的參數(shù)可以接受指向null的對(duì)象,然后在調(diào)用方法內(nèi)部必須完成對(duì)象的實(shí)體化。??

5. 結(jié)論

完成了對(duì)值類(lèi)型與引用類(lèi)型的論述,在這些知識(shí)積累的基礎(chǔ)上,本文期望通過(guò)深入的論述來(lái)進(jìn)一步的分享參數(shù)傳遞的藝術(shù),解開(kāi)層層疑惑的面紗。從探討問(wèn)題的角度來(lái)說(shuō),參數(shù)傳遞的種種誤區(qū)其實(shí)根植與對(duì)值類(lèi)型和引用類(lèi)型的本質(zhì)理解上,因此完成了對(duì)類(lèi)型問(wèn)題的探討再進(jìn)入?yún)?shù)傳遞的迷宮,我們才會(huì)更加游刃有余。我想,這種探討問(wèn)題的方式,也正是我們追逐問(wèn)題的方式,深入進(jìn)入.NET的高級(jí)殿堂是繞不開(kāi)這一選擇的。

?

參考文獻(xiàn)

(USA)Jeffrey Richter, Applied Microsoft .NET Framework Programming

(USA)David Chappell, Understanding .NET

?

轉(zhuǎn)載于:https://www.cnblogs.com/thx-bj/archive/2008/05/28/1208799.html

總結(jié)

以上是生活随笔為你收集整理的[你必须知道的.NET]第十二回:参数之惑---传递的艺术(下)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日日涩| 欧美一区二区三区影视 | 中文字幕在线看人 | av在线综合网 | 口述3p做爰全过程 | 福利在线观看 | 一区二区三区四区日韩 | 欧美日韩国产成人 | 欧美乱大交 | 国产香蕉网 | 国产美女一区二区 | 黄色片播放器 | 天堂在线 | 亚洲国产美女视频 | 天天插夜夜爽 | 国产超级av在线 | 成人一级视频在线观看 | 午夜精品区| 欧美日韩一区二区久久 | 久久久久久国产精品视频 | 成人免费高清在线播放 | 蜜桃视频成人在线观看 | 91啪国产在线 | 97人人在线视频 | 高潮毛片无遮挡 | 天天舔日日操 | 久久精品福利视频 | 精品无码久久久久久久久果冻 | 国产又黄又猛又粗又爽 | 日韩av电影网 | 国偷自拍第113页 | 懂色中文一区二区在线播放 | 欧美午夜大片 | 尤物av无码色av无码 | 最新日韩在线视频 | 一级免费观看视频 | 亚洲人一区二区三区 | 成人18网站 | 亚洲爆乳无码精品aaa片蜜桃 | 男女日批网站 | 下面一进一出好爽视频 | 久久91视频 | 99久久精品免费看 | 国产精品无码无卡无需播放器 | 五月天黄色网 | xxx.国产| 国产区精品区 | 快灬快灬一下爽69 | 不卡av电影在线 | 天天做夜夜做 | 在线观看中文字幕av | 丰满少妇高潮一区二区 | 一级理论片 | 91久久精品日日躁夜夜躁国产 | 午夜视频在线观看免费视频 | 久久精品激情 | 日韩欧美不卡视频 | 中文字幕一区二区三区乱码不卡 | 国产乱码一区二区三区播放 | 精品人妻一区二区三区潮喷在线 | 欧美精品123| 国产69精品久久久久999小说 | 美女扒开让男人桶爽 | 成人毛片软件 | www.4hu95.com四虎| chinesepron hd videos国产91| 日韩精品 欧美 | 天天综合网久久 | 一区二区网 | 日本精品视频一区二区 | 人妖一区二区三区 | 4438x五月天 日吊视频 | 特黄a级片 | 操操操操网| 人人看超碰 | 日日碰碰 | 日韩特级黄色片 | 高清无码一区二区在线观看吞精 | 99视频导航 | 精品处破女学生 | 一级特黄aa| 韩国黄色精品 | 88国产精品视频一区二区三区 | 香蕉久草| 国产精品久久久久久久毛片 | 公侵犯一区二区三区 | 日韩免费网 | 亚洲国产视频网站 | 欧美视频一区二区三区在线观看 | 91国偷自产一区二区三区观看 | 久久久久亚洲av无码a片 | 欧美一级视频免费观看 | 青草视频在线看 | 强开乳罩摸双乳吃奶羞羞www | 91麻豆成人精品国产 | 国产乱轮视频 | 黑人玩弄人妻一区二区三区影院 | 免费黄色欧美 | 狠狠操很很干 |