我最近看到以下代码:
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
.实际上,已经有很多关于它的文章和信息。例如this article很好。
但是我没有找到关于这个新声明的任何信息
null!
有人可以给我一个解释吗?为什么我需要使用这个?
和
line1
有什么区别和 line2
?
最佳答案
了解什么的关键null!
意思是理解!
运营商。 您之前可能已经将它用作“非”运算符。但是,由于 C# 8.0 和它的新 "nullable-reference-types"功能,运算符(operator)得到了第二个含义。它可以用于 类型 为了控制可空性,它被称为 "Null Forgiving Operator"
典型用法
假设这个定义:
class Person
{
// Not every person has a middle name. We express "no middle name" as "null"
public string? MiddleName;
}
用法是:void LogPerson(Person person)
{
Console.WriteLine(person.MiddleName.Length); // WARNING: may be null
Console.WriteLine(person.MiddleName!.Length); // No warning
}
此运算符基本上关闭了针对此用法的编译器空值检查。技术说明
零安全
C# 8.0 试图帮助您管理您的
null
-值。而不是允许您分配 null
默认情况下,他们对所有内容进行了翻转,现在需要您明确标记您希望能够容纳的所有物品 null
值(value)。这是一个 super 有用的功能,它可以让你避免
NullReferenceException
s 通过强制您做出决定并执行它。工作原理
在谈论空安全时,变量可以处于 2 种状态。
Since C# 8.0 all reference types are non-nullable by default. Value types have been non-nullable since C# 2.0!
“可空性”可以通过 2 个新的(类型级)运算符进行修改:
!
= 来自 Nullable
至 Non-Nullable
?
= 来自 Non-Nullable
至 Nullable
这些运算符是彼此对应的。
Compiler 使用您通过这些运算符定义的信息来确保空值安全。
例子
?
运算符(operator)使用。这个运算符告诉编译器一个变量可以保存一个空值。
string? x;
x
是引用类型 - 因此默认情况下不可为空。 ?
运算符 - 这使它可以为空。 x = null
工作正常。 string y;
y
是引用类型 - 因此默认情况下不可为空。 y = null
生成警告,因为您将空值分配给不应为空的内容。 很高兴知道:使用
string?
是 System.Nullable<string>
的语法糖!
运算符(operator)使用。这个操作符告诉编译器一些可能为空的东西是可以安全访问的。 在这种情况下,您表达了“不关心”空安全的意图。
string x;
string? y;
x = y
Warning: "y" may be null
x = y!
y
是带有 ?
的引用类型应用了类型修饰符,因此如果没有另外证明,它可以为空。 !
至 y
其中覆盖 它的可空性设置使其成为 不可为空 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,自 起,使用可能是系统设计缺陷的征兆。它否定了编译器保证的空安全的影响。
推理
使用
!
运算符(operator)会产生很难找到的错误。 如果您有一个标记为不可为空的属性,您将假定您可以安全地使用它。但是在运行时,你突然遇到了 NullReferenceException
抓挠你的头。由于在使用 !
绕过编译器检查后,值实际上变为空值。 .那为什么会存在这个运算符呢?
存在适合使用的有效用例(在下面详细概述)。但是,在 99% 的情况下,您最好使用替代解决方案。请不要打几十个
!
在您的代码中,只是为了使警告静音。null
时检查代码的行为。通过。 好吗!?但什么是
null!
是什么意思?它告诉编译器
null
不是 nullable
值(value)。听起来很奇怪,不是吗? 同
y!
从上面的例子。 它看起来很奇怪,因为您将运算符应用于 null
文字 .但概念是一样的。在这种情况下,null
文字与任何其他表达式/类型/值/变量相同。null
文字类型是默认情况下唯一可以为空的类型!但正如我们所了解的,任何类型的可空性都可以用 !
覆盖。不可为空。 类型系统不关心变量的实际/运行时值。只有它的编译时类型以及在您的示例中要分配给
LastName
的变量( null!
) 是 non-nullable
,就类型系统而言这是有效的。考虑一下这段(无效的)代码。
object? null;
LastName = null!;
关于c# - 什么是空!声明是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54724304/