新的 c# 可空选项
New c# nullable option
在新版本的 C# 中,默认选项可为 nullable。我是说这个
这对我来说真是个好功能。但是我不明白一件事。 属性 可以由我还是由程序为空?
我知道这个 属性 永远不应该为空,因为我在表格中填写它并且从未将其设置为空。但通常它可以为空。应该怎么标注?
示例:
用户模型:
public string? Name { get; set; }
public string Name { get; set; } = null!
我真的很困惑。
如果值可以为空,并且 <Nullable>enable</Nullable>
值在您的 *.csproj
文件中设置,您 必须将这些值声明为可为空。
在您给出的示例中,可空类型(而不是将 null 分配为默认值)是可行的方法:
public string? Name {get; set;}
您还会注意到 VS 会在您每次引入 属性 等可以为空但未标记为空的内容时向您发出警告。
I know that this property should never be null because I fill it in
the form and never set it as null. But in general it can be null. How
should I mark it?
如果在构造函数中将其设置为 non-null,那么您可以将其声明为 string
而不是 string?
,因为它确实保证永远不会为 null。
但是,如果它在构造函数具有 运行 之后(并且在调用任何其他方法之前)为空,则它可以为空,您应该将其声明为 string?
.
你面临的二分法是(根据你所说的)当正确使用 class 时它永远不应该为 null - 即如果调用代码确实调用了初始化 [=55= 的方法] 到 non-null 在访问它之前,它将保证不为 null - 这意味着你想将它声明为 non-null string
这样调用者就不需要使用null-forgiving !
运算符抑制可为 null 的警告。
遇到这种情况怎么办?那么我认为你有三种可能性:
- 将 属性 声明为可为 null:
string?
并让调用者抑制可为 null 的警告或检查该值是否为 null。
- 将 属性 初始化为 non-null 默认值,例如
string.Empty
并将 属性 声明为不可空 string
.
- 假设在 属性 为 null 时访问它是一个编程错误,并抛出适当的异常。
对于最后一种情况,您可以这样做:
private string? _name;
public string Name
{
get
{
if (_name == null)
throw new InvalidOperationException("Do not access Name without setting it to non-null or calling Init()");
return _name;
}
set
{
if (value == null)
throw new ArgumentNullException("value", "You cannot set Name to null.");
_name = value;
}
}
这里假定有一个名为 Init()
的方法可以调用它来初始化 Name
,当然您的代码可能会有所不同。
无论您采用哪种方法,您都应该真正检查 属性 setter 中的空值,如上所示。
请注意,编写 setter 空检查的更简洁的方法是:
set
{
_name = value ?? throw new ArgumentNullException("value", "You cannot set Name to null.");
}
在新版本的 C# 中,默认选项可为 nullable。我是说这个
这对我来说真是个好功能。但是我不明白一件事。 属性 可以由我还是由程序为空?
我知道这个 属性 永远不应该为空,因为我在表格中填写它并且从未将其设置为空。但通常它可以为空。应该怎么标注?
示例:
用户模型:
public string? Name { get; set; }
public string Name { get; set; } = null!
我真的很困惑。
如果值可以为空,并且 <Nullable>enable</Nullable>
值在您的 *.csproj
文件中设置,您 必须将这些值声明为可为空。
在您给出的示例中,可空类型(而不是将 null 分配为默认值)是可行的方法:
public string? Name {get; set;}
您还会注意到 VS 会在您每次引入 属性 等可以为空但未标记为空的内容时向您发出警告。
I know that this property should never be null because I fill it in the form and never set it as null. But in general it can be null. How should I mark it?
如果在构造函数中将其设置为 non-null,那么您可以将其声明为 string
而不是 string?
,因为它确实保证永远不会为 null。
但是,如果它在构造函数具有 运行 之后(并且在调用任何其他方法之前)为空,则它可以为空,您应该将其声明为 string?
.
你面临的二分法是(根据你所说的)当正确使用 class 时它永远不应该为 null - 即如果调用代码确实调用了初始化 [=55= 的方法] 到 non-null 在访问它之前,它将保证不为 null - 这意味着你想将它声明为 non-null string
这样调用者就不需要使用null-forgiving !
运算符抑制可为 null 的警告。
遇到这种情况怎么办?那么我认为你有三种可能性:
- 将 属性 声明为可为 null:
string?
并让调用者抑制可为 null 的警告或检查该值是否为 null。 - 将 属性 初始化为 non-null 默认值,例如
string.Empty
并将 属性 声明为不可空string
. - 假设在 属性 为 null 时访问它是一个编程错误,并抛出适当的异常。
对于最后一种情况,您可以这样做:
private string? _name;
public string Name
{
get
{
if (_name == null)
throw new InvalidOperationException("Do not access Name without setting it to non-null or calling Init()");
return _name;
}
set
{
if (value == null)
throw new ArgumentNullException("value", "You cannot set Name to null.");
_name = value;
}
}
这里假定有一个名为 Init()
的方法可以调用它来初始化 Name
,当然您的代码可能会有所不同。
无论您采用哪种方法,您都应该真正检查 属性 setter 中的空值,如上所示。
请注意,编写 setter 空检查的更简洁的方法是:
set
{
_name = value ?? throw new ArgumentNullException("value", "You cannot set Name to null.");
}