繁体   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