如何告诉编译器必须初始化 属性
how to tell compiler that property MUST be initialized
我有一个 class 比如这个:
public class Foo
{
public string Bar { get; init; }
public IImmutableSet<int> Baz { get; init; }
}
当我那样写的时候,我得到一个编译器警告
Non-nullable property 'Bar' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. csharp(CS8618)
有很多内容解决这个问题(例如 ),但据我所知,它只是关于如何通过设置默认值或关闭编译器来消除消息使用 null!
.
等“假默认值”的警告
但就我而言,默认值没有意义。
相反,我想告诉编译器必须显式设置这些属性,这样如果在使用对象之前没有设置任何属性,编译器就会抱怨。就像未赋值局部变量的情况一样:
这可能吗,如果可以,怎么办?
我知道我可以只定义一个带参数的构造函数,因此使用该构造函数是创建新实例的唯一方法。但是因为我有很多像上面那样的 classes,所以我需要写很多额外的代码(即构造函数)。如果有一种“必须初始化”标志,我的代码的读者也会更清楚。
使属性具有私有设置函数,并创建一个构造函数,您可以在其中设置这些私有 属性 值。
我可以使用 positional records:
public class Foo(string Bar, IImmutableSet<int> Baz);
我会在这一行中同时获得属性和构造函数。
但这只有在我需要值语义时才有意义。
我认为 get;
只有具有构造函数的属性才是可行的方法。
public class C
{
public C(string a)
{
A = a;
}
public string A { get; }
}
I would need to write quite of lot of extra code (i.e. the constructors).
现在创建构造函数非常容易。需要:
Ctrl+.
+ 在 VS Code 中单击鼠标 1 次:
Ctrl+.
+ 向下箭头 + 在 VS 中输入:
微软怎么说?
1。 Working with Nullable Reference Types
In Working with Nullable Reference Types in Non-nullable properties and initialization shows 3 options:
一个。构造函数
Constructor binding is a useful technique to ensure that your non-nullable properties are initialized:
b。可为空的支持字段
Unfortunately, in some scenarios constructor binding isn't an option; navigation properties, for example, cannot be initialized in this way.
(...)
One way to deal with these scenarios, is to have a non-nullable property with a nullable backing field:
C#
private Address? _shippingAddress;
public Address ShippingAddress
{
set => _shippingAddress = value;
get => _shippingAddress
?? throw new InvalidOperationException("Uninitialized property: " + > nameof(ShippingAddress));
}
c。强制初始化为null!
作为一个更简洁的替代方案,可以借助 null-forgiving 运算符 (!):
将 属性 简单地初始化为 null
C#
public Product Product { get; set; } = null!;
An actual null value will never be observed except as a result of a programming bug, e.g. accessing the navigation property without properly loading the related entity beforehand.
2。 Learn techniques to resolve nullable warnings
在 Learn techniques to resolve nullable warnings 中同样没有 get; init;
属性的示例,文章建议了两个选项来处理警告:
- 构造函数
- 初始化为
null!;
to indicate that a member is initialized in other code.
3。 Attributes for null-state static analysis interpreted by the C# compiler
对于更复杂的场景,可能值得查看 Attributes for null-state static analysis interpreted by the C# compiler 并使用一些可用的属性。不过,我认为这不是日常代码的路径。
我有一个 class 比如这个:
public class Foo
{
public string Bar { get; init; }
public IImmutableSet<int> Baz { get; init; }
}
当我那样写的时候,我得到一个编译器警告
Non-nullable property 'Bar' must contain a non-null value when exiting constructor. Consider declaring the property as nullable. csharp(CS8618)
有很多内容解决这个问题(例如 null!
.
但就我而言,默认值没有意义。 相反,我想告诉编译器必须显式设置这些属性,这样如果在使用对象之前没有设置任何属性,编译器就会抱怨。就像未赋值局部变量的情况一样:
这可能吗,如果可以,怎么办?
我知道我可以只定义一个带参数的构造函数,因此使用该构造函数是创建新实例的唯一方法。但是因为我有很多像上面那样的 classes,所以我需要写很多额外的代码(即构造函数)。如果有一种“必须初始化”标志,我的代码的读者也会更清楚。
使属性具有私有设置函数,并创建一个构造函数,您可以在其中设置这些私有 属性 值。
我可以使用 positional records:
public class Foo(string Bar, IImmutableSet<int> Baz);
我会在这一行中同时获得属性和构造函数。 但这只有在我需要值语义时才有意义。
我认为 get;
只有具有构造函数的属性才是可行的方法。
public class C
{
public C(string a)
{
A = a;
}
public string A { get; }
}
I would need to write quite of lot of extra code (i.e. the constructors).
现在创建构造函数非常容易。需要:
Ctrl+.
+ 在 VS Code 中单击鼠标 1 次:Ctrl+.
+ 向下箭头 + 在 VS 中输入:
微软怎么说?
1。 Working with Nullable Reference Types
In Working with Nullable Reference Types in Non-nullable properties and initialization shows 3 options:
一个。构造函数
Constructor binding is a useful technique to ensure that your non-nullable properties are initialized:
b。可为空的支持字段
Unfortunately, in some scenarios constructor binding isn't an option; navigation properties, for example, cannot be initialized in this way. (...) One way to deal with these scenarios, is to have a non-nullable property with a nullable backing field: C#
private Address? _shippingAddress; public Address ShippingAddress { set => _shippingAddress = value; get => _shippingAddress ?? throw new InvalidOperationException("Uninitialized property: " + > nameof(ShippingAddress)); }
c。强制初始化为null!
作为一个更简洁的替代方案,可以借助 null-forgiving 运算符 (!):
将 属性 简单地初始化为 nullC#
public Product Product { get; set; } = null!;
An actual null value will never be observed except as a result of a programming bug, e.g. accessing the navigation property without properly loading the related entity beforehand.
2。 Learn techniques to resolve nullable warnings
在 Learn techniques to resolve nullable warnings 中同样没有 get; init;
属性的示例,文章建议了两个选项来处理警告:
- 构造函数
- 初始化为
null!;
to indicate that a member is initialized in other code.
3。 Attributes for null-state static analysis interpreted by the C# compiler
对于更复杂的场景,可能值得查看 Attributes for null-state static analysis interpreted by the C# compiler 并使用一些可用的属性。不过,我认为这不是日常代码的路径。