如何让 C# 意识到方便属性的可空性?
How to make C# aware of the nullability of convenient properties?
考虑这个代码片段,它没有可为 null 的警告。
public class Foo {
public string Property { get; } = "Some String";
}
public class Bar {
[DisallowNull]
public Foo? Foo { get; private set; }
[MemberNotNull(nameof(Foo))]
public void MyMethod() {
Foo = new Foo();
// After setting Foo, I use Foo.Property in some way
Console.WriteLine(Foo.Property);
}
}
由于在我的真实代码中,我在设置Foo
后使用Foo.Property
很多,我想添加一个“方便属性 " 到 Bar
直接 returns 它,这样我就可以使用更短的名称访问它(Foo
在我的真实代码中实际上是一个相当长的名称):
// in Bar
public string? Property => Foo?.Property;
// ...
// Now I can do:
Console.WriteLine(Property);
但是,现在Bar.Property
是可以为空的,即使在Foo
肯定不为空的地方(比如刚刚设置Foo
之后)。因此,当我在不允许使用 null 的地方使用 Property
时,编译器会给我警告。
我以为我需要的是用NotNullIfMemberNotNull(nameof(Foo))
之类的东西来注释Property
,但是在查找之后,this attribute is only proposed, and doesn't exist yet。
我该如何解决这个问题?
我想出的一个解决方法是让 Foo
和 Property
都有支持字段。在Foo
的setter中,也设置Property
。这样,我们就可以在Foo
的setter中添加MemberNotNull
属性了。
private Foo? foo;
[DisallowNull]
public Foo? Foo {
get => foo;
[MemberNotNull(nameof(Property))]
private set {
foo = value;
Property = value.Property;
}
}
public string? Property { get; private set; }
然而,这不是很普遍。它之所以有效,是因为 Foo
恰好被标记为 DisallowNull
.
首先,MemberNotNull
是一个 post 条件,它仅向调用者发出信号,表明指定成员在成员 returns 之后不会为 null。不幸的是,它不会在方法本身内帮助您。
我知道你正在使用一个更大模式的简化,但我建议重写 MyMethod
的一种方法是:
public void MyMethod() {
var foo = new Foo();
Foo = foo;
Console.WriteLine(foo.Property);
}
考虑这个代码片段,它没有可为 null 的警告。
public class Foo {
public string Property { get; } = "Some String";
}
public class Bar {
[DisallowNull]
public Foo? Foo { get; private set; }
[MemberNotNull(nameof(Foo))]
public void MyMethod() {
Foo = new Foo();
// After setting Foo, I use Foo.Property in some way
Console.WriteLine(Foo.Property);
}
}
由于在我的真实代码中,我在设置Foo
后使用Foo.Property
很多,我想添加一个“方便属性 " 到 Bar
直接 returns 它,这样我就可以使用更短的名称访问它(Foo
在我的真实代码中实际上是一个相当长的名称):
// in Bar
public string? Property => Foo?.Property;
// ...
// Now I can do:
Console.WriteLine(Property);
但是,现在Bar.Property
是可以为空的,即使在Foo
肯定不为空的地方(比如刚刚设置Foo
之后)。因此,当我在不允许使用 null 的地方使用 Property
时,编译器会给我警告。
我以为我需要的是用NotNullIfMemberNotNull(nameof(Foo))
之类的东西来注释Property
,但是在查找之后,this attribute is only proposed, and doesn't exist yet。
我该如何解决这个问题?
我想出的一个解决方法是让 Foo
和 Property
都有支持字段。在Foo
的setter中,也设置Property
。这样,我们就可以在Foo
的setter中添加MemberNotNull
属性了。
private Foo? foo;
[DisallowNull]
public Foo? Foo {
get => foo;
[MemberNotNull(nameof(Property))]
private set {
foo = value;
Property = value.Property;
}
}
public string? Property { get; private set; }
然而,这不是很普遍。它之所以有效,是因为 Foo
恰好被标记为 DisallowNull
.
首先,MemberNotNull
是一个 post 条件,它仅向调用者发出信号,表明指定成员在成员 returns 之后不会为 null。不幸的是,它不会在方法本身内帮助您。
我知道你正在使用一个更大模式的简化,但我建议重写 MyMethod
的一种方法是:
public void MyMethod() {
var foo = new Foo();
Foo = foo;
Console.WriteLine(foo.Property);
}