Winforms构造函数时序错误
本文关键字:错误 构造函数 Winforms | 更新日期: 2023-09-27 18:36:40
我有以下Winforms层次结构。
Form ==> AForm ==> BForm
并且在 FormA
中定义了一个可空的成员int? X;
。而在FormB
中,有以下代码。
public partial class FormA: Form
{
public int? X { get; set; }
public FormA(int? x) { X = x }
....
public partial class FormB: FormA, IFormAView
{
public FormB()
{
AsyncCall(() =>
{
int z = X ?? 0;
System.Diagnostics.Debug.WriteLine("X: " + X.ToString() + " z: " + z.ToString());
return z;
}
public static T GetForm<T>(int? x)
{
T form = new T();
form.X = x;
form.Show();
}
GetForm<FormB>(100);
X
从未被分配为 null 或零。我正在尝试关闭并打开表单FormB
。有时z
为零(可能每 10 次一次)。我设置了一个条件中断,当z==0
在行return z
时中断。
命中断点时。调试写入
X: z: 0
甚至调试也显示 FormA:X 不为零。
您正在另一个线程上调用代码来测试 X(使用 AsyncCall 和"X ??"),该代码可能会也可能不会在 FormA 构造函数中分配 X 之前或之后运行。
也就是说,如果您停止使用AsyncCall,则应获得一致的结果。
在 FormA 中,X 是一个可为 Null 的 int 属性,默认为 null
。 您永远不会从public FormB()
构造函数调用public FormA(int? x)
基构造函数,因此 X 永远不会设置为其他任何内容。
由于在调用 FormB 的构造函数(调用 AsyncCall)后设置 X 的值,因此会遇到计时问题,因为 AsyncCall 可能会在 GetForm 函数中设置form.X = x;
之前或之后强制。
如果您希望 AsyncCall 仍然是 AsyncCall,则应将 FormB() 的构造函数更新为如下所示:
public FormB(int? x) : base(x){ //...
然后按如下方式更新 GetForm(注意 where 子句,这让我们知道 T 至少是从 FromA 派生的,所以它有一个接受 int 的构造函数?
public static T GetForm<T>(int? x) where T : FormA
{
T form = new T(x);
form.Show();
}