我可以告诉 C# 可为空的引用一个方法实际上是对字段的空检查吗
Can I tell C# nullable references that a method is effectively a null check on a field
考虑以下代码:
#nullable enable
class Foo
{
public string? Name { get; set; }
public bool HasName => Name != null;
public void NameToUpperCase()
{
if (HasName)
{
Name = Name.ToUpper();
}
}
}
在 Name=Name.ToUpper() 上,我收到一条警告,指出 Name 可能是空引用,这显然是不正确的。我可以通过内联 HasName 来解决这个警告,所以条件是 if (Name != null).
有什么方法可以指示编译器,HasName 的真实响应意味着对 Name 的不可为空性约束?
这很重要,因为 HasName 实际上可能会测试更多的东西,我可能想在几个地方使用它,或者它可能是 API 表面的 public 部分。有很多理由想要将 null 检查纳入它自己的方法中,但这样做似乎会破坏可为 null 的引用检查器。
String是引用类型,nullable(例如int?
)是可以为null的值类型。所以你不能真的这样做 string? myString
;你需要的是:
class Foo
{
public string Name { get; set; }
public bool HasName => !String.IsNullOrEmpty(Name); ////assume you want empty to be treated same way as null
public void NameToUpperCase()
{
if (HasName)
{
Name = Name.ToUpper();
}
}
}
更新:
C# 9.0 以 MemberNotNullWhenAttribute 的形式介绍了您正在寻找的内容。在你的情况下你想要:
#nullable enable
class Foo
{
public string? Name { get; set; }
[MemberNotNullWhen(true, nameof(Name))]
public bool HasName => Name != null;
public void NameToUpperCase()
{
if (HasName)
{
Name = Name.ToUpper();
}
}
}
还有 MemberNotNullAttribute 用于无条件断言。
旧答案:
我查看了 System.Diagnostics.CodeAnalysis
的不同属性,但找不到任何适用的东西,这非常令人失望。最接近您想要的似乎是:
public bool TryGetName([NotNullWhen(true)] out string? name)
{
name = Name;
return name != null;
}
public void NameToUpperCase()
{
if (TryGetName(out var name))
{
Name = name.ToUpper();
}
}
它看起来很笨重,我知道。你可以看看the MSDN docs for nullable attributes,也许你会找到更整洁的东西。
在 C# 9.0 中检查 [MemberNotNull(nameof(Property))]
和 [MemberNotNullWhen(true, nameof(Property))]
属性。
考虑以下代码:
#nullable enable
class Foo
{
public string? Name { get; set; }
public bool HasName => Name != null;
public void NameToUpperCase()
{
if (HasName)
{
Name = Name.ToUpper();
}
}
}
在 Name=Name.ToUpper() 上,我收到一条警告,指出 Name 可能是空引用,这显然是不正确的。我可以通过内联 HasName 来解决这个警告,所以条件是 if (Name != null).
有什么方法可以指示编译器,HasName 的真实响应意味着对 Name 的不可为空性约束?
这很重要,因为 HasName 实际上可能会测试更多的东西,我可能想在几个地方使用它,或者它可能是 API 表面的 public 部分。有很多理由想要将 null 检查纳入它自己的方法中,但这样做似乎会破坏可为 null 的引用检查器。
String是引用类型,nullable(例如int?
)是可以为null的值类型。所以你不能真的这样做 string? myString
;你需要的是:
class Foo
{
public string Name { get; set; }
public bool HasName => !String.IsNullOrEmpty(Name); ////assume you want empty to be treated same way as null
public void NameToUpperCase()
{
if (HasName)
{
Name = Name.ToUpper();
}
}
}
更新:
C# 9.0 以 MemberNotNullWhenAttribute 的形式介绍了您正在寻找的内容。在你的情况下你想要:
#nullable enable
class Foo
{
public string? Name { get; set; }
[MemberNotNullWhen(true, nameof(Name))]
public bool HasName => Name != null;
public void NameToUpperCase()
{
if (HasName)
{
Name = Name.ToUpper();
}
}
}
还有 MemberNotNullAttribute 用于无条件断言。
旧答案:
我查看了 System.Diagnostics.CodeAnalysis
的不同属性,但找不到任何适用的东西,这非常令人失望。最接近您想要的似乎是:
public bool TryGetName([NotNullWhen(true)] out string? name)
{
name = Name;
return name != null;
}
public void NameToUpperCase()
{
if (TryGetName(out var name))
{
Name = name.ToUpper();
}
}
它看起来很笨重,我知道。你可以看看the MSDN docs for nullable attributes,也许你会找到更整洁的东西。
在 C# 9.0 中检查 [MemberNotNull(nameof(Property))]
和 [MemberNotNullWhen(true, nameof(Property))]
属性。