【发布时间】:2020-07-18 12:59:50
【问题描述】:
假设我们有一个简单的User 类,它有一个电话号码的可选(可为空)属性:
public class User
{
public string? PhoneNumber { get; private set; }
}
然后,在其他课程中,我需要使用用户的电话号码,如果有的话:
public static void Example(User user)
{
if (!(user.PhoneNumber is null))
{
DoSomething(user.PhoneNumber);
}
}
这工作正常,但甚至不接近具有以下内容的可读性:
public class User
{
public string? PhoneNumber { get; private set; }
public bool HasPhoneNumber => !(PhoneNumber is null);
}
然后像这样使用它:
public static void Example(User user)
{
if (user.HasPhoneNumber)
{
DoSomething(user.PhoneNumber);
}
}
在 C# 8 的 null 安全性更改之前,这一直很好。现在,上面的代码触发了一个 CS8604。这当然是编译器的预期行为,但我仍在寻找一种方法来避免将is null(或!= null)检查分散在整个代码库中。有没有办法告诉编译器在调用方法(或另一个属性)后某个属性不为空,类似于[NotNullWhen] 属性对参数的作用?
【问题讨论】:
-
这是
string的“有价值”模式:PhoneNumber?.Length > 0 -
@aepot 我的问题不在于属性的实现,而在于用法。我需要一种方法告诉编译器,当
HasPhoneNumber属性为真时,PhoneNumber不为空。 -
如何告诉编译器运行时变量的值状态?编译器不处理运行时值。现在你告诉编译器它可以用
?为空。您可以将string?替换为string。抱歉,我是菜鸟,不知道string?的任何原因,因为普通的string也可以是null。 -
作为一个简单的字符串,也可以测试
if ([User].PhoneNumber is string s) { // non null, use s } else { // is null, complain because it's private set and you cannot add one } -
@GurGaller 请检查下一个问题:How to avoid irrelevant nullable warning (without explicit suppression)。我认为问题是一样的。该问题的解决方案将在
C# 9中提供。
标签: c# properties c#-8.0 nullable-reference-types