无效是什么!声明是什么意思? [英] What does null! statement mean?

查看:104
本文介绍了无效是什么!声明是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近看过以下代码:

public class Person
{
    //line 1
    public string FirstName { get; }
    //line 2
    public string LastName { get; } = null!;
    //assign null is possible
    public string? MiddleName {get; } = null;

    public Person(string firstName, string lastName, string middleName)
    {
        FirstName = firstName;
        LastName = lastName;
        MiddleName = middleName;
    }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
        MiddleName = null;
    }
}

基本上,我尝试挖掘c#8的新功能.其中之一是NullableReferenceTypes.实际上,已经有很多文章和信息.例如. 这篇文章很好. 但是我找不到有关此新语句null!的任何信息 有人可以向我提供解释吗?为什么我需要使用这个? line1line2有什么区别?

Basically I try to dig into new c# 8 features. One of them is NullableReferenceTypes. Actually there're a lot of articles and information about it already. E.g. this article is quite good. But I din't find any information about this new statement null! Can someone provide to me explanation for it ? Why I need to use this ? And what is difference between line1 and line2 ?

推荐答案

理解null!含义的关键是理解!运算符.您之前可能已将其用作非"运算符.但是从C#8.0开始,该运算符还可以用于控制Nullabilty的类型

The key to understanding what null! means is understanding the ! operator. You may have used it before as the "not" operator. But since C#8.0 the operator can also be used on a type to control Nullabilty

!运算符在类型上使用时,称为

The ! operator, when used on a type, is called the Null Forgiving Operator [docs]. It was introduced in C# 8.0

假设这个定义:

class Person
{
  public string? MiddleName;
}

用法为:

void LogPerson(Person person)
{
    Console.WriteLine(person.MiddleName.Length);  // WARNING: may be null
    Console.WriteLine(person.MiddleName!.Length); // No warning
}

此运算符基本上会关闭编译器的空检查.

This operator basically turns off the compiler null checks.

使用此运算符告诉编译器可以安全地访问的内容可以为空.您表示打算在这种情况下不关心"空安全性.

Using this operator tells the compiler that something that could be null, is safe to be accessed. You express the intent to "not care" about null safety in this instance.

在谈论null安全性时,变量可以处于2种状态.

There are 2 states a variable can be in - when talking about null-safety.

  • 可为空-可以为空.
  • 不可为空-不能为空.
  • Nullable - Can be null.
  • Non-Nullable - Can not be null.

自C#8.0起,默认情况下所有引用类型都是不可为空的.

Since C# 8.0 all reference types are Non-nullable by default.

可以通过以下两个新的类型操作符来修改可空性":

The "nullability" can be modified by these 2 new type-operators:

  • ! =从NullableNon-Nullable
  • ? =从Non-NullableNullable
  • ! = From Nullable to Non-Nullable
  • ? = From Non-Nullable to Nullable

这些运算符基本上是彼此对应的. 编译器使用您使用这些运算符定义的信息来确保null安全.

These operators are basically counterparts to one another. The Compiler uses the information - you define with those operators - to ensure null-safety.

  1. 可空string? x;

  • x是引用类型-因此默认情况下不可为空.
  • 我们应用?运算符-使其可以为空.
  • x = null正常工作.
  • x is a reference type - So by default non-nullable.
  • We apply the ? operator - which makes it nullable.
  • x = null Works fine.

不可为空的string y;

  • y是引用类型-因此默认情况下不可为空.
  • y = null生成警告,因为您为不应该为null的对象分配了null值.
  • y is a reference type - So by default non-nullable.
  • y = null Generates a warning since you assign a null value to something that is not supposed to be null.

!操作员用法.

! Operator usage.

string x;
string? y = null;

  1. x = y

  • 非法! -Warning: "y" may be null
  • 分配的左侧不可为空,而右侧则可为空.

x = y!

  • 法律!
  • 分配的左右两侧不可为空.
  • y!开始工作,将!运算符应用于y,这使其不可为空.
  • Legal!
  • The right and left side of the assignment is non-nullable.
  • Works since y! Applies the ! operator to y which makes it non-nullable.

警告 !运算符仅在类型系统级别关闭编译器检查-在运行时,该值可能仍为null.

WARNING The ! operator only turns off the compiler-checks at a type-system level - At runtime, the value may still be null.

这是反模式.

您应该尝试使用! Null-Forgiving-Operator 避免.

This is an Anti-Pattern.

You should try to avoid using the ! Null-Forgiving-Operator.

在此操作员适合使用的情况下,有有效的用例(在下面详细介绍),例如单元测试.但是,在99%的情况下,使用替代解决方案会更好.请不要在您的代码中拍打几十个!,只是为了静默警告.考虑一下您的原因是否真的值得使用.

There are valid use-cases ( outlined in detail below ) like unit-tests where this operator is appropriate to use. In 99% of the cases though, you are better off with an alternative solution. Please do not slap dozens of !'s in your code, just to silence the warnings. Think if your cause really warrants the use.

使用-但要小心.如果没有具体目的/用例,请不要使用它.

Use - but with care. If there is no concrete purpose / use-case prefer not to use it.

它抵消了编译器保证的null安全性的影响.

It negates the effects of null-safety you get guaranteed by the compiler.

使用!运算符将很难发现错误.如果您拥有标记为不可为空的属性,则可以安全使用它.但是在运行时,您突然遇到NullReferenceException并挠头.由于使用!绕过编译器检查后,值实际上变为空.

Using the ! operator will create very hard to find bugs. If you have a property that is marked non-nullable, you will assume you can use it safely. But at runtime, you suddenly run into a NullReferenceException and scratch your head. Since a value actually became null after bypassing the compiler-checks with !.

  • 在某些情况下,编译器无法检测到可为空的值实际上是不可为空的.
  • 更容易的遗留代码库迁移.
  • 在某些情况下,您根本不在乎某些东西是否为空.
  • 使用单元测试时,您可能需要检查null通过时的代码行为.
  • In some edge cases, the compiler is not able to detect that a nullable value is actually non-nullable.
  • Easier legacy code-base migration.
  • In some cases, you just don't care if something becomes null.
  • When working with Unit-tests you may want to check the behavior of code when a null comes through.

它告诉编译器null不是null值.听起来很奇怪,不是吗?

It tells the compiler that null is not a null value. Sounds weird, doesn't it?

与上面示例中的y!相同. 自从您将运算符应用于null文字以来,它看起来就很奇怪.但是概念是相同的.

It is the same as y! from the example above. It only looks weird since you apply the operator to the null literal. But the concept is the same.

public string LastName { get; } = null!;

此行定义类型为string的名为LastName的不可为空的类属性. 由于它是不可为空的,因此从技术上讲,您不能为它分配null.

This line defines a non-nullable class property named LastNameof type string. Since it is non-nullable you can technically not assign null to it - obviously.

但是您只是这样做-通过使用!运算符将null分配给LastName.因为null!不为null-就编译器所关心的null安全而言.

But you do just that - assign null to LastName - by using the ! operator. Because null! is not null - as far as the compiler is concerned about null-safety.

这篇关于无效是什么!声明是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆