在WinForms中,常见的初始化函数是初始化参考变量(例如)
class SomeClass : Form {
Button b;
SomeClass() {
InitializeComponents();
}
SomeClass(Container x) {
InitializeComponents();
}
void InitializeComponents() {
b = new Button();
}
}
如您所见,b始终被初始化为非null值。但是,C#8仍然会抱怨SomeClass()不会初始化不可为空的值b。
我当然可以将b标记为可为空(按钮?b),但是,由于未检查可为空性(它不能为null ...),因此现在我将对b的每次使用发出警告。
解决此问题的最佳方法是什么。是否有一个属性可用于将InitializeComponent标记为始终由构造方法调用?
请注意,这是WinForms(每个组件...)中非常常见的模式
Yuval
答案 0 :(得分:3)
按照assign:
问:为什么对已初始化的字段报告警告? 是由构造函数间接地还是在构造函数外部?A:编译器识别当前字段中明确分配的字段 仅构造函数,并警告声明为不可为空的其他字段。 这忽略了字段初始化的其他方式,例如工厂 方法,辅助方法,属性设置器和对象初始化器。我们 将调查识别常见的初始化模式以避免 不必要的警告。
因此,现在无法实现您想要的目标,而无需将该分配直接移到构造函数中(或在声明它的行上分配它)。
答案 1 :(得分:2)
对于您的非常具体的示例,解决方案是将InitializeComponent()
合并到默认构造函数中,并从第二个构造函数中调用它。
class SomeClass : Form {
private readonly Button b;
public SomeClass() {
b = new Button();
}
public SomeClass(Container x): this() {
// Something else...
}
}
不幸的是,这是众所周知的当前限制,而且,所有设计人员生成的代码都不会遵循这种模式,因此您可能需要放置一些#nullable disable
(或其他适当的一条指令)在这里和那里。
答案 2 :(得分:-1)
设为私有字段: 私人System.Windows.Forms.Button button1;