国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

C#: in ,out, ref 到底有沒(méi)用的深入分析

2019-11-14 11:56:46
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

C#.net 提供的3個(gè)關(guān)鍵字,in,out,ref開(kāi)發(fā)中會(huì)經(jīng)常用到,那么它們3個(gè)如何使用呢,又有什么區(qū)別,我查了下csdn和知乎的總結(jié),都有點(diǎn)老了,說(shuō)的也不細(xì)致。我盡量通過(guò)代碼示例寫(xiě)的言簡(jiǎn)意賅寫(xiě)。

1 in in只用在委托和接口中; 例子:

//測(cè)試模型 class Model { public int a { get; set; } public Model(int a) { this.a = a; } }//創(chuàng)建3個(gè)實(shí)例List<Model> modelList= new List<Model>() { new Model(1), new Model(4), new Model(6) };//調(diào)用foreach接口,試著操作3個(gè)實(shí)例,賦值為nullmodelList.ForEach(e=>e=null); //查看結(jié)果://modelList的取值不變。

分析原因,F(xiàn)orEach的參數(shù)是委托函數(shù):

//ForEach方法:public void ForEach(Action<T> action);//委托聲明:public delegate void Action<in T>(T obj);

委托是泛型的,類(lèi)型T前加了一個(gè)關(guān)鍵字in,因?yàn)閹в嘘P(guān)鍵字in,所以T obj是不能被修改的。

嘗試測(cè)試:

//修改元素e的屬性amodelList.ForEach(e=>{e.a*=2;});

結(jié)果每個(gè)元素都乘以2,變?yōu)?,8,12。可知,可以修改對(duì)象的屬性。

2 out

out 關(guān)鍵字用法注意: 1)帶有out的形參,在函數(shù)定義時(shí),return前必須給函數(shù)賦一個(gè)值。 2)調(diào)用函數(shù)時(shí),帶有out的參數(shù)不必賦一個(gè)初始值。 3)out形參傳值是通過(guò)引用(by reference)

out使用場(chǎng)景: 在函數(shù)返回多個(gè)值時(shí),通常用out 返回其中一個(gè)

public bool Operation(out Model updateMod){ updateMode = new Model(5); try{ // my operation ... // return true; } catch{ //寫(xiě)入日志 return false; }}//使用Model um; //未初始化bool rtnMsg = Operation(out um); //如果初始化,傳值通過(guò)reference//分析://返回um,如果rntMsg為ture,則um按照預(yù)想邏輯被賦值,//如果rntMsg為false 則um未按照預(yù)想邏輯被賦值。

3 ref

ref關(guān)鍵字用于改變參數(shù)傳遞,將by value修改為by reference傳值,原來(lái)是by reference傳遞的,加上ref還是不加ref,效果是一樣的。

例如:

public void reviseModel(int a){ a = 12;}Model model = new Model(10);//調(diào)用reviseModelreviseModel(model.a); //model.a仍然=10;by-valuereviseMode(ref model.a); //編譯不過(guò),提示ref后的參數(shù)不歸類(lèi)與變量int a;reviseMode(ref a); //如果不給變量a賦一個(gè)初始值,//編譯器也是提示:調(diào)用前未被賦值的錯(cuò)誤//因此賦值int a= model.a; //變量a初始值為10;reviseMode(ref a);//修改變量a=12;但是model.a的值仍然為10

如何修改對(duì)象model中的屬性a,將其變?yōu)?2呢?

//直接將參數(shù)設(shè)為Model對(duì)象,則函數(shù)調(diào)用時(shí),傳值通過(guò)by referencepublic void reviseModel(Model md){ md.a = 12;}reviseModel(model );//傳值通過(guò)by reference

因此,ref關(guān)鍵詞使用總結(jié): ref的話(huà),用于處理值變量,如基本類(lèi)型、結(jié)構(gòu)等,它們不需要被new出來(lái),傳值依照的是值拷貝。

1)ref 后的變量,如果是值類(lèi)型(value type),那么加上ref后變?yōu)榘凑?by reference傳值;

2)ref 后的變量,如果是引用類(lèi)型(reference type),那么加上ref與不加沒(méi)有任何區(qū)別;

3)ref后的變量,使用前必須賦值

4)ref后的變量不能是引用類(lèi)型的屬性

以上是基本的分析,在使用中就夠了,如果想更深入的分析這個(gè)問(wèn)題,請(qǐng)繼續(xù)。

4 深入探討out ref

主要分析out ref 到底有何用,不用他們會(huì)有什么影響。

1) C#中有一類(lèi)方法,名字叫作Try…,如Int.TryParse,它返回一個(gè)bool值,嘗試解析一個(gè)字符串,如果成功解析為整數(shù),則返回true,得到的整數(shù)作為第二個(gè)out的int被傳出。 見(jiàn)分析文章 異常設(shè)計(jì)準(zhǔn)則 DateTime.TryParse和Parse 從文章中看出,相比沒(méi)有out參數(shù)的次方法Parse,如果解析字符串失敗,則會(huì)拋出一個(gè)參數(shù)錯(cuò)誤的異常。

用Try…方法寫(xiě)出來(lái)的代碼比try…catch寫(xiě)出來(lái)的要簡(jiǎn)潔,于是這也變成了out參數(shù)使用的一個(gè)常用場(chǎng)景。

2) java和C#比較

在Java里,HashMap

// HashMap<K, V> map;// K key;V val = map.get(key);if (val != null) { // ...}

但val == null,既可能是該map里尚未有鍵為該key的鍵值對(duì),也可能是已經(jīng)有該鍵值對(duì)了但是其值為null。 要區(qū)分兩者,HashMap提供了containsKey()方法。所以正確的寫(xiě)法是這樣的:

// HashMap<K, V> map;// K key;if (map.containsKey(key)) { V val = map.get(key); // ...}

containsKey()跟get()的內(nèi)部操作幾乎是一模一樣的,都要做一次hash查找,只是返回了查找結(jié)果的不同部分而已。也就是說(shuō)按照這種“正確寫(xiě)法”來(lái)寫(xiě)的話(huà),訪(fǎng)問(wèn)一次HashMap就有雙倍開(kāi)銷(xiāo)了。杯具!

C#有許多這種細(xì)節(jié)設(shè)計(jì)比Java更貼心。看C#用out關(guān)鍵詞如何改進(jìn)這個(gè)問(wèn)題。

System.Collections.Generic.Dictionary

TryGetValue:Dictionary(TKey, TValue).TryGetValue Method (TKey, TValue) (System.Collections.Generic)public bool TryGetValue( TKey key, out TValue value)ParameterskeyType: TKeyThe key of the value to get.valueType: TValue

利用這個(gè)方法,上面的Java代碼對(duì)應(yīng)的C#版就可以寫(xiě)成:

// Dictionary<TKey, TValue> dict;// TKey key;TValue val;if (dict.TryGetValue(key, out val)) { // ...}

這就把ContainsKey與Item[Key]的語(yǔ)義結(jié)合了起來(lái),把一次hash查找能找到的信息一口氣都返回出來(lái),從源頭上避免了“兩次查找”的冗余操作,有利于程序的性能。


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 长兴县| 平顶山市| 海丰县| 扶风县| 平谷区| 信阳市| 东阳市| 靖安县| 城口县| 库车县| 凤城市| 鄯善县| 靖远县| 鲜城| 嵩明县| 新津县| 永嘉县| 呼伦贝尔市| 准格尔旗| 昌江| 儋州市| 石柱| 商城县| 吉木乃县| 芒康县| 融水| 临海市| 广汉市| 麻栗坡县| 阳西县| 黎平县| 丰镇市| 平度市| 黎川县| 禹城市| 双鸭山市| 辽阳县| 广东省| 柞水县| 无棣县| 大埔区|