【问题标题】:Nullable reference types and constructor warnings可为空的引用类型和构造函数警告
【发布时间】:2020-07-28 01:51:15
【问题描述】:

我正在尝试在我的项目中采用 C# 8 的可为空引用类型,并使其与 EF Core 顺利配合。

this guide 之后,我使我的实体类具有构造函数,该构造函数接受初始化其不可为空属性所需的所有数据:

public class MyEntity
    {
        public MyEntity(int someNumber, string name, string shortName, bool active)
        {
            SomeNumber= someNumber;
            Name = name;
            ShortName = shortName;
            Active = active;
        }

        public int SomeNumber { get; set; }
        public string Name { get; set; }
        public string ShortName { get; set; }
        public string? SomethingOptional { get; set; }
        public bool Active { get; set; }
    }

在我的业务案例中,我有时需要更新实体的所有属性。我可以使用属性设置器,但由于我想通过加倍初始化语法来确保不会遗漏任何内容(实际上我的实体可以有 10 个或更多属性),为了方便起见,我决定创建一个公共 Update() 函数并调用它而不是构造函数体:

        public MyEntity(int someId, string name, string shortName, bool active)
        {
            Update(someId, name, shortName, active);
        }

        public void Update(int someId, string name, string shortName, bool active)
        {
            SomeNumber = someId;
            Name = name;
            ShortName = shortName;
            Active = active;
        }

现在,在创建实体时,我调用构造函数,在更改它时,我调用 Update()。 但是,现在编译器会给出可空性警告 (CS8618),即构造函数未初始化不可为空的属性。显然无法猜测调用 Update 会初始化它们。

我可能使用 Update() 方法对其进行了过度设计,但现在我很好奇 有没有办法让编译器相信我的构造函数会初始化属性? p>

【问题讨论】:

    标签: c# constructor entity-framework-core c#-8.0 nullable-reference-types


    【解决方案1】:

    确实有点冗长,但是你可以使用 .NET 5 中的[MemberNotNull] 属性告诉编译器一个方法确保一个成员返回后不为空。

    using System.Diagnostics.CodeAnalysis;
        
    public class MyEntity
    {
        [MemberNotNull(nameof(Name), nameof(ShortName))]
        public void Update(int someId, string name, string shortName, bool active)
        {
            SomeNumber = someId;
            Name = name;
            ShortName = shortName;
            Active = active;
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果你确定你在做什么,那么你可以通过

      来抑制编译器警告
      #pragma warning disable CS8618
      public MyEntity(int someNumber, string name, string shortName, bool active)
      {
          SomeNumber= someNumber;
          Name = name;
          ShortName = shortName;
          Active = active;
      }
      #pragma warning disable CS8618
      

      还有一个开放的case for that in github,你可以查一下。您可以使用下面的方法(引用自github)

      class MyClass
      {
          private string m_str1;
          private string m_str2;
      
          public MyClass()
          {
              Init(out m_str1, out m_str2);
          }
      
          private void Init(out string str1, out string str2)
          {
              str1 = string.Empty;
              str2 = string.Empty;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-30
        • 1970-01-01
        • 2022-01-08
        • 2013-08-13
        • 2022-01-23
        • 1970-01-01
        相关资源
        最近更新 更多