簡體   English   中英

滿足或靜音可為空的泛型類型屬性警告

[英]Satisfy or silence nullable generic type property warning

在 C#8.0 中使用可空引用類型,給出這個簡化的代碼,其中 T 可以是任何值類型或引用類型,而空值是引用類型 T 實例的有效值:

public class C<T>
{
    public T P { get; set; }
}

編譯器發出警告CS8618 "Non-nullable property 'P' is uninitialized. Consider declaring the property as nullable." . 我怎樣才能滿足編譯器並消除這個警告(不抑制 CS8618)?

是否有我可以應用的屬性或類型參數約束? 這種情況怎么辦?

我想出的最好的是

public T P { get; set; } = default!;

但我希望有一種方法可以在不使用 null-forgiving/“dammit” 運算符('!')的情況下做到這一點。

注意:您不能將屬性的類型聲明為T? - CS8627。 此外,這意味着返回的任何值類型都是Nullable<T> ,這不是預期的。 閱讀更多關於這個,例如在這里。


編輯:我注意到這也有效:

public class C<T>
{
    public C()
    {
        P = default;
    }
    [AllowNull]
    public T P { get; set; }
}

但是,我更願意使用自動屬性初始化程序。

基本上, classstruct空性是不兼容的,不能組合。

您的選擇包括:

  • 保持你的類完全通用; 所以,在你的班級中沒有區分TT? . 這仍然允許C<int>C<int?> ,只是不允許T? .

  • 根據您的要求,限制為classstruct

  • 編寫兩個單獨的類,一個用於結構,一個用於引用類型。

如果它們足夠簡單,編寫兩個類也不錯。 您可以將非通用部分推送到基類中以避免過多重復。

當您實例化您的類時,屬性 P 的值將為空,這就是您看到警告的原因。

實例化類時需要確保該值不為空,唯一的方法是定義一個構造函數並為P提供值。 由於T是泛型類型,您有兩個選擇:

  1. 將值作為構造函數參數傳遞或
  2. 約束T以能夠創建新實例
// Option #1
public class C<T>
{
   C(T p)
   {
       P = p
   }

   public T P { get; set; }
}

// option #2:
public class C<T> where T : new()
{
   C()
   {
       P = new T()
   }

   public T P { get; set; }
}

暫無
暫無

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

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