簡體   English   中英

C#6.0中的Monadic null檢查

[英]Monadic null checking in C# 6.0

我偶然發現了一個有趣的網站,其中解決了C#6.0的一些新的(提議的)功能。 您可以在這里閱讀: 可能的C#6.0功能

我覺得特別有趣的是monadic null檢查(也稱為null-propagation操作符 )。 根據網站,以下聲明

var bestValue = points?.FirstOrDefault()?.X ?? -1;

包含monadic null檢查,目前使用這段代碼實現:

if (points != null) 
{
  var next = points.FirstOrDefault();
  if (next != null && next.X != null) return next.X;
}   
return -1;

我的第一眼就是,嘿,這里寫的是什么? 但在查看“舊”代碼后,我開始喜歡它了。

但是,我也開始提出一些問題,我想問一下。

  • 我假設這個null傳播的運算符是線程安全的。 但這實際上是如何進行的? 種族條件會被刪除還是會持續存在?
  • 該運算符如何處理泛型類型? 而且,它如何處理無約束的泛型類型? 例如,考慮一下

     var resultAfterNullCheck = x?.Y; 

    如果這里的類型Y用引用類型,非可空值類型和可空值類型實例化,那么就沒有任何合理的做法(因為我不知道該怎么做,因為我根本不知道該怎么做)。 那么是否會返回默認值? 或者它會拋出錯誤?

  • 在查看站點提供的示例(以及我在上面復制的示例)時,我假設null-propagation運算符的一個主要好處是它只會評估語句一次。 然而(也許是由於我對CLR的了解不足),我很好奇它是如何進行的。
    對我來說,第一個評估(如果points等於null)應該觸發擴展方法FirstOrDefault()在points不為null時觸發,然后將返回類型的evalation設置為null或者不是,否則,X將是回來。 那么這些實際上是三個評估合二為一? 或者我不正確地理解它? 這會影響執行速度嗎?

換句話說,什么會更快,執行空檢查的舊方法,或這個新的可愛運算符? 我將在Visual Studio 2015下載完成后立即通過執行一些研究來檢查這一點...但這需要一點耐心......

對這種新的操作員類型有什么想法嗎? 它真的還是一個提議的,或者我們真的可以期望使用這個新的monadic null檢查嗎?

編輯
正如Matthew Watson提供了一篇很好的MSDN討論這個(以及更多)主題的文章 ,我很好奇它是否提到了我之前關於無約束泛型的問題以及該運算符如何處理它。 不幸的是,我還沒有找到答案。 雖然我認為程序員應該試圖阻止使用無約束泛型,但我仍然可以想象這有時是不可行的。 如果是這樣的話,重新設計是否真的有必要?

你是在暗示這個。 你的問題一個接一個:

  1. 你為什么認為它的線程安全? 調用成員函數不是。 這只是通過預檢查空值來調用成員函數,因此您只能獲得與原始函數保證一樣多的線程安全性。

  2. 如果您的泛型類型允許空值比較(這是此操作符將在幕后使用),則將發出代碼。 如果不是,您將收到編譯錯誤(例如,如果您要求類型為值類型)。 這涵蓋了所有情況!

  3. 它被稱為每個操作符,就像正常一樣. 運營商。 如果你說Abc它仍然是兩個級別的間接,並且使用這個新的運算符沒什么不同,它只是檢查空值。

真正的好處?. 是它的語義(你可以一目了然地告訴你的代碼試圖做什么)和短路(使代碼比嵌套if短得多)。 你不會取代每一個. 在您的舊代碼中?. 事實上你可能很少使用它。 但有些情況下它會很有用,比如在Linq表達式中跟隨...OrDefault()操作或調用事件。

根據John Skeet在他的博客中 ,部分回答你的第一個問題,空條件運算符?. (= null傳播運算符)是線程安全的。

您可以在Roslyn項目討論中找到有關計划功能的所有信息。 你也可以嘗試使用Roslyn的控制台應用程序的新功能,如nuget-package(這意味着它適用於Visual Studio 2013 <)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM