close

這幾日剛好在 Stack overflow 看到了一篇文章。邏輯很簡單,概念卻很有意思,所以決定做個註記。
(原文列於參考資料)

 

 

 

假設情境


  已有一個客戶類別,包含「名稱」屬性。

    public class Customer

    {

        public string Name { get; set; }

    }

  要取客戶的名稱,寫法很簡單就如下 :

   

    var name = customer.Name;

 

  然而當customer為null時,程式就會報錯。此時可以「三元條件運算子」修改如下 : 

 

    var name = customer == null ? null : customer.Name;

 

 

 

 

Null-conditional operators


  在 C# 6.0 推出新的運算子 ?. 。在 docs 的說明為

  • 若 a 為 null ,則 a?.x 的結果為 null。
  • 若 a 為非 null ,則a?.x的結果同a.x。

  

  此時,上述範例可改寫如下 : 

 

    var name = customer?.Name;

 

  變得精簡許多,並與原本三元條件運算子的寫法,會得到一樣的結果。

 

  那假如是DateTime?.Value呢

 

    DateTime? datetime = null; // Maybe from database

    var time = datetime.Value;

 

  Nullable 的 DateTime,若在執行階段取Value時遇到null,會發生錯誤 : 「System.InvalidOperationException: 可為 Null 的物件必須具有值。」。

  也許有人會很直覺的想到 : 「那就加上Null-conditional operators吧!」,如此會收到編輯階段錯誤 : 「'DateTime'未包含'Value'的定義,也找不到可接受類型'DateTime'第一個引數的可存取擴充方法'Value'」。

  其原因在於Null-conditional operators的規則 : e?.x =>   ((e == null) ? null : e0.x),e0等同於e。若 e 為 Nullable 型別,則此狀況下 e0 為 e.Value。依此規則代換,原本的寫法意即

 

    var time = datetime.Value.Value;

 

  因此會出現編輯階段錯誤。到這裡或許有人已經想到 : DateTime?.Value 這樣的寫法,其實就等同 DateTime? 本身。

 

  改用Default Value呢

  某些情況下,假如無法使用 null 也可以考慮以 Default Value 作為替代,只是自身不是很喜歡這個做法。以DateTime來說,Default Value為「0001/1/1 上午 12:00:00」 、 int的Default Value為「0」 , 甚至 string 的 Default Value 是「null」! 在閱讀上較不直觀。

 

       DateTime? datetime = null;

       var timeDefaule = datetime.GetValueOrDefault();

       var defaultTime = datetime ?? default(DateTime);

 

 

 

 

結語


  依照每個系統的狀況與需求,資料型別的設定與邏輯都會有不同的變化。

  看到文章一時間引發了好奇心,沒有特別遇過這個情境真沒有想到有如此狀況。

  若有其他情境或解法也歡迎大家分享~

 

  參考資料

arrow
arrow
    創作者介紹
    創作者 律晴音 的頭像
    律晴音

    聆風之境

    律晴音 發表在 痞客邦 留言(0) 人氣()