iT邦幫忙

0

在 C# 中 Nullable Reference Types 使用屬性MemberNotNullWhen

c#
  • 分享至 

  • xImage
  •  

承上文 在 C# 中 Nullable Reference Types 使用屬性MemberNotNull

我們繼續探討...


使用屬性 MemberNotNullWhen
假設一個例子

class Person
{
  static readonly Regex _nameReg = new Regex(@"^I'm \w*");

  private string _name;

  public Person(string name)
  {
    if (!TryInitialize(name))
      _name = "invalid name";
  }

  private bool TryInitialize(string name)
  {
    if (_nameReg.IsMatch(name))
    {
      _name = name;
      return true;
    }
    else
      return false;
  }
}

這段程式碼定義了一個類別 Person,在這個類別中有一個正規表達式物件_nameReg定義成唯讀與靜態屬性,它是用來匹配名字是否符合特定格式。

類別中還有一個私有字串屬性 _name 和一個建構子方法 public Person(string name),建構子方法中有一個判斷式,如果呼叫 TryInitialize 方法傳回的值是 false,就將 _name 屬性初始化為字串 "invalid name"

類別中還有一個私有方法 private bool TryInitialize(string name),它會使用 _nameReg 屬性來匹配傳入的名字字串,如果匹配成功就將 _name 屬性初始化為傳入的名字,並傳回布林值。

接著,編譯器將對上面的程式碼發出警告:
https://ithelp.ithome.com.tw/upload/images/20230110/20152569DtZnhRj3cY.jpg

警告訊息如下:

警告	CS8618	退出建構函式時,不可為 Null 的 欄位 '_name' 必須包含非 Null 值。請考慮將 欄位 宣告為可為 Null。

按照警告提示他希望你在變數或參數型別前面加上 ?,來表示這個型別可以是空值。例如private string? _name;
但在這個實作中,明明在建構子中將會為 _name 屬性賦值,所以它不可能在建構子結束時為空值。

要解決這種情況,您可以使用屬性MemberNotNullWhen:

[MemberNotNullWhen(true, nameof(_name))]
private bool TryInitialize(string name)

MemberNotNullWhen 屬性是 C# 8.0 中新引入的可空性偵錯工具,
它可以讓你在執行階段確保特定條件下,某個成員不會是空值。

加入後 編譯器的警告 就消失了
https://ithelp.ithome.com.tw/upload/images/20230110/20152569tgA32sZIHz.jpg

如果你嘗試對 _name 屬性進行存取,但是它是空值,則會拋出 NullReferenceException 例外。
這個屬性可以讓你在程式碼中清楚地表達你的意圖,並讓程式在執行階段更穩定。

了解更多:MemberNotNullWhenAttribute Class


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言