真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

在NullObject中C#6.0有哪些改進(jìn)

今天就跟大家聊聊有關(guān)在NullObject中C#6.0有哪些改進(jìn),可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作,成都做網(wǎng)站公司-創(chuàng)新互聯(lián)建站已向1000多家企業(yè)提供了,網(wǎng)站設(shè)計(jì),網(wǎng)站制作,網(wǎng)絡(luò)營(yíng)銷等服務(wù)!設(shè)計(jì)與技術(shù)結(jié)合,多年網(wǎng)站推廣經(jīng)驗(yàn),合理的價(jià)格為您打造企業(yè)品質(zhì)網(wǎng)站。

什么是空引用異常

作為一個(gè)敲過(guò)代碼的碼農(nóng)來(lái)說(shuō),似乎沒(méi)有誰(shuí)沒(méi)有遇到過(guò)NullReferenceException這 個(gè)問(wèn)題,有些時(shí)候當(dāng)方法內(nèi)部調(diào)用一個(gè)屬性、方法(委托)時(shí),我們控制這些屬性在“外部”的表現(xiàn)(當(dāng)然某些情況下使用ref關(guān)鍵字除外),所以我們要在方法 的內(nèi)部去判斷屬性、委托方法是否為Null來(lái)避免可能的、錯(cuò)誤使用上帶來(lái)的空引用異常,這樣當(dāng)我們知道如果對(duì)象為Null的話,我們會(huì)實(shí)現(xiàn)符合我們“預(yù) 期”的行為。

解決空引用異常---Check Any Where

這很簡(jiǎn)單,我只要在需要用的地方檢查一下是否為Null就可以了。是的,這非常簡(jiǎn)單,語(yǔ)義也很清晰,但是當(dāng)你要重復(fù)檢查一個(gè)對(duì)象實(shí)體10000萬(wàn)次時(shí),你的代碼中將存在10000個(gè)如下代碼段:

public void Check()         {             if (Person.AlivePerson() != null)             {                 Person.AlivePerson().KeepAlive = true;             }          }

你能容忍這樣的行為嗎?

If(OK)

Continue;

Else

Close;

應(yīng)用NullObject設(shè)計(jì)模式

NullObjectPattern出自forth by Gamma(設(shè)計(jì)模式4人組),核心內(nèi)容是:提供一個(gè)給定對(duì)象的空值代理,空值代理中提供不做任何事情的方法實(shí)現(xiàn)。

接下來(lái)讓我們看看維基百科上的C#實(shí)現(xiàn):

// compile as Console Application, requires C# 3.0 or higher using System; using System.Linq; namespace MyExtensionWithExample {     public static class StringExtensions {          public static int SafeGetLength(this string valueOrNull) {              return (valueOrNull ?? string.Empty).Length;          }     }     public static class Program {         // define some strings         static readonly string[] strings = new [] { "Mr X.", "Katrien Duck", null, "Q" };         // write the total length of all the strings in the array         public static void Main(string[] args) {             var query = from text in strings select text.SafeGetLength(); // no need to do any checks here             Console.WriteLine(query.Sum());         // The output will be: 18          }     } }

在C#語(yǔ)言中,我們通過(guò)靜態(tài)的擴(kuò)展方法來(lái)實(shí)現(xiàn)將檢查方式統(tǒng)一在方法內(nèi)部,而不是寫的到處都是,上面的例子中是在String類上實(shí)現(xiàn)了一個(gè)SafeGetLength擴(kuò)展方法,將為所有String類型提供了一個(gè)方法,這樣我們?cè)凇按a整潔”上又進(jìn)了一步。

下面我們?cè)賮?lái)看一個(gè)更常用的例子---來(lái)自于StackOverFlow

public static class EventExtensions     {         public static void Raise(this EventHandler evnt, object sender, T args)             where T : EventArgs         {             if (evnt != null)             {                 evnt(sender, args);             }         }     }

***,說(shuō)一個(gè)細(xì)節(jié)問(wèn)題,以上代碼均沒(méi)有實(shí)現(xiàn)“線程安全”,在大牛Eric Lippert的文章中針對(duì)線程安全有過(guò)一個(gè)更精彩的討論,請(qǐng)戳這里。

改進(jìn)后的代碼時(shí)在方法內(nèi)部增加了一個(gè)臨時(shí)變量,作為方法內(nèi)部的拷貝,實(shí)現(xiàn)線程安全,如果有疑問(wèn)請(qǐng)參考我的《C#堆vs?!分袑?duì)方法內(nèi)部變量在堆棧上的表現(xiàn)一章。

public class SomeClass     {         public event EventHandler MyEvent;          private void DoSomething()         {             var tmp = MyEvent;              tmp.Raise(this, EventArgs.Empty);         }     }

 

更“潮”的方式-C#6.0語(yǔ)法

    來(lái)自MSDN Magazine的Mark Michaelis(《C#本質(zhì)論》作者)給我們介紹了C#6.0在語(yǔ)言可能帶來(lái)的新改進(jìn),其中就有針對(duì)“Null條件運(yùn)算符”的改進(jìn)。

C#6.0更多參考:

Part One: https://msdn.microsoft.com/zh-cn/magazine/dn683793.aspx

Part Two: https://msdn.microsoft.com/zh-cn/magazine/dn802602.aspx

即使是 .NET 開(kāi)發(fā)新手,也可能非常熟悉 NullReferenceException。有一個(gè)例外是幾乎總是會(huì)指出一個(gè) Bug,因?yàn)殚_(kāi)發(fā)人員在調(diào)用 (null) 對(duì)象的成員之前未進(jìn)行充分的 null 檢查。請(qǐng)看看以下示例:

public static string Truncate(string value, int length) {   string result = value;   if (value != null) // Skip empty string check for elucidation   {     result = value.Substring(0, Math.Min(value.Length, length));   }   return result; }

如果不進(jìn)行 null 檢查,此方法會(huì)引發(fā) NullReferenceException。盡管這很簡(jiǎn)單,但檢查字符串參數(shù)是否為 null 的過(guò)程卻稍微有些繁瑣。通常,考慮到比較的頻率,該繁瑣的方法可能沒(méi)有必要。C# 6.0 包括一個(gè)新的 null 條件運(yùn)算符,可幫助您更加簡(jiǎn)便地編寫這些檢查:

public static string Truncate(string value, int length) {             return value?.Substring(0, Math.Min(value.Length, length)); }  [TestMethod] public void Truncate_WithNull_ReturnsNull() {   Assert.AreEqual(null, Truncate(null, 42)); }

根據(jù) Truncate_WithNull_ReturnsNull 方法所演示的內(nèi)容,如果對(duì)象的值實(shí)際上為 null,則 null 條件運(yùn)算符將返回 null。這帶來(lái)了一個(gè)問(wèn)題,即 null 條件運(yùn)算符在調(diào)用鏈中出現(xiàn)時(shí)會(huì)是什么情況?如以下示例中所示:

public static string AdjustWidth(string value, int length) {   return value?.Substring(0, Math.Min(value.Length, length)).PadRight(length); }  [TestMethod] public void AdjustWidth_GivenInigoMontoya42_ReturnsInigoMontoyaExtended() {   Assert.AreEqual(42, AdjustWidth("Inigo Montoya", 42).Length); }

盡管 Substring 是通過(guò) null 條件運(yùn)算符進(jìn)行調(diào)用的,并且 null value?.Substring 似乎返回了 null,但語(yǔ)言行為按您的想法進(jìn)行。這簡(jiǎn)化了對(duì) PadRight 的調(diào)用過(guò)程,并立即返回 null,從而避免會(huì)導(dǎo)致出現(xiàn) NullReferenceException 的編程錯(cuò)誤。這個(gè)概念稱為“null 傳播”。

Null 條件運(yùn)算符會(huì)根據(jù)具體條件進(jìn)行 null 檢查,然后再調(diào)用目標(biāo)方法以及調(diào)用鏈中的所有其他方法。這將可能產(chǎn)生一個(gè)令人驚訝的結(jié)果,例如,text?.Length.GetType 語(yǔ)句中的結(jié)果。

如果 null 條件運(yùn)算符在調(diào)用目標(biāo)為 null 時(shí)返回 null,那么調(diào)用會(huì)返回值類型的成員時(shí)最終會(huì)是什么數(shù)據(jù)類型(假定值類型不能為 null)?例如,從 value?.Length 返回的數(shù)據(jù)類型不能只是 int。答案當(dāng)然是:可以為 null 的類型(int?)。實(shí)際上,嘗試僅將結(jié)果分配給 int 將會(huì)出現(xiàn)編譯錯(cuò)誤:

int length = text?.Length; // Compile Error: Cannot implicitly convert type 'int?' to 'int'

Null 條件具有兩種語(yǔ)法形式。首先,問(wèn)號(hào)在點(diǎn)運(yùn)算符前面 (?.)。其次,將問(wèn)號(hào)和索引運(yùn)算符結(jié)合使用。例如,給定一個(gè)集合(而非在索引到集合之前顯式進(jìn)行 null 檢查),您就可以使用 null 條件運(yùn)算符執(zhí)行此操作:

public static IEnumerable GetValueTypeItems(   IList collection, params int[] indexes)   where T : struct {   foreach (int index in indexes)   {     T? item = collection?[index];     if (item != null) yield return (T)item;   } }

此示例使用了運(yùn)算符 ?[…] 的 null 條件索引形式,導(dǎo)致僅在集合不為 null 時(shí)才索引到集合。通過(guò) null 條件運(yùn)算符的此形式,T? item = collection?[index] 語(yǔ)句在行為上相當(dāng)于:

T? item = (collection != null) ? collection[index] : null.

請(qǐng)注意,null 條件運(yùn)算符僅可檢索項(xiàng)目,不會(huì)分配項(xiàng)目。如果給定 null 集合,那么這意味著什么?

請(qǐng)注意針對(duì)引用類型使用 ?[…] 時(shí)的隱式歧義。由于引用類型可以為 null,因此對(duì)于集合是否為 null,或者是否元素本身實(shí)際上就是 null 而言,來(lái)自 ?[…] 運(yùn)算符的 null 結(jié)果不明確。

Null 條件運(yùn)算符的一個(gè)非常有用的應(yīng)用程序解決了 C# 自 C# 1.0 以來(lái)一直存在的的一個(gè)特性,即在調(diào)用委托之前檢查是否為 null。我們來(lái)看一下中顯示的 C# 2.0 代碼。

圖 1 在調(diào)用委托之前檢查是否為 Null

class Theremostat {   event EventHandler OnTemperatureChanged;   private int _Temperature;   public int Temperature   {     get     {       return _Temperature;     }     set     {       // If there are any subscribers, then       // notify them of changes in temperature       EventHandler localOnChanged =         OnTemperatureChanged;       if (localOnChanged != null)       {         _Temperature = value;         // Call subscribers         localOnChanged(this, value);       }     }   } }

通過(guò)使用 null 條件運(yùn)算符,整個(gè) set 實(shí)現(xiàn)過(guò)程就可簡(jiǎn)化為:

OnTemperatureChanged?.Invoke(this, value)

現(xiàn)在,您只需對(duì)將 null 條件運(yùn)算符作為前綴的 Invoke 進(jìn)行調(diào)用,不再需要將委托實(shí)例分配給本地變量,從而實(shí)現(xiàn)線程安全,甚至是在調(diào)用委托之前顯式檢查值是否為 null。

C# 開(kāi)發(fā)人員都很想知道在***的四個(gè)版本中是否對(duì)此內(nèi)容有所改進(jìn)。答案是最終進(jìn)行了改進(jìn)。僅此一項(xiàng)功能就可以改變調(diào)用委托的方式。

另一個(gè) null 條件運(yùn)算符普及的常見(jiàn)模式是與 coalesce 運(yùn)算符結(jié)合使用。您無(wú)需在調(diào)用 Length 之前對(duì) linesOfCode 進(jìn)行 null 檢查,而是可以編寫項(xiàng)目計(jì)數(shù)算法,如下所示:

List linesOfCode = ParseSourceCodeFile("Program.cs"); return linesOfCode?.Count ?? 0;

在這種情況下,任何空集合(無(wú)項(xiàng)目)和 null 集合均標(biāo)準(zhǔn)化為返回相同數(shù)量??傊琻ull 條件運(yùn)算符將實(shí)現(xiàn)以下功能:

1. 如果操作數(shù)為 null,則返回 null

2. 如果操作數(shù)為 null,則簡(jiǎn)化調(diào)用鏈中的其他調(diào)用

3. 如果目標(biāo)成員返回一個(gè)值類型,則返回可以為 null 的類型 (System.Nullable)。

4. 以線程安全的方式支持委托調(diào)用

5. 可用作成員運(yùn)算符 (?.) 和索引運(yùn)算符 (?[…])

看完上述內(nèi)容,你們對(duì)在NullObject中C#6.0有哪些改進(jìn)有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。


標(biāo)題名稱:在NullObject中C#6.0有哪些改進(jìn)
文章網(wǎng)址:http://weahome.cn/article/pgosoh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部