【问题标题】:Proper implementation NRT in ASP.NET Core在 ASP.NET Core 中正确实现 NRT
【发布时间】:2019-08-28 11:45:09
【问题描述】:

对于作为 ASP.NET Core MVC 中 C# 8.0 一部分的可空引用类型,我几乎没有疑问:

  1. 当存在带有字符串参数的操作 (public IActionResult Index(string message)) 时,如果未传递给操作,则参数仍可为空。这个问题的官方解决方案是什么?还需要检查null吗?

  2. 当存在简单的可变模型时,如何正确修改为 NRT?例如 Scott Allen (https://odetocode.com/blogs/scott/archive/2019/08/07/think-twice-before-returning-null.aspx) 建议创建 NullUser。这是正确的吗? Maybe<T> 声音也不适合 NRT。可变和不可变模型的官方解决方案是什么?

    public class User
    {
        public int UserId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public IEnumerable<Message> Messages { get; set; }
    }
    
    public class Message
    {
        public int MessageId { get; set; }
        public string Text { get; set; }
    }
    
  3. 现在我经常使用FirstOrDefault 来从集合中提取某些内容(并且在检查 null 之后)。集合不为空,但可以为空,现在当想要使用 First 时会抛出异常,这是不好的,因为它是一个操作,并且想要在不尝试 (https://softwareengineering.stackexchange.com/questions/387674/c-8-non-nullable-references-and-the-try-pattern) 和 try-catch 的情况下创建错误的响应。再次Maybe&lt;T&gt; 听起来不是解决方案。这个问题的官方解决方案是什么?

我知道我不需要避免空值,而是希望将它们最小化并遵循 NRT,因为它听起来像未来之歌

【问题讨论】:

    标签: c# asp.net-core c#-8.0 nullable-reference-types


    【解决方案1】:

    你让这件事变得太难了。可空引用类型只是一个编译器提示——一种更明确地说明您实际期望一段代码做什么的方式。它真的不会改变任何事情的运作方式。

    例如,在一个动作参数的情况下。如果您的string 参数可以为空(不是应该,而是可以 - 这很重要),那么它应该是string?。动作参数几乎总是可选的,所以它们当然可以为空。唯一的例外是路由参数,因为除非路由参数填充了某些东西,否则您实际上不会执行此操作。例如,假设它是通过查询字符串填充的,那么它肯定可以为空,你应该在那里使用string?。如果要确保它不为空,则需要使用标准的空保护:

    if (message == null)
        return BadRequest();
    

    可变性也与此无关。同样,您所做的只是明确说明引用是否可能为空。这也适用于您的第三个问题。查询总是有可能与数据库中的行不匹配,然后返回 null。使用First 并不是确保返回实际值的某种方式;在这种情况下,它只会抛出异常。在这种情况下,您应该继续使用FirstOrDefault,使用User?/Message?(或只是var),然后像往常一样进行空检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-12
      • 1970-01-01
      相关资源
      最近更新 更多