Winforms构造函数时序错误?

时间:2012-06-08 18:32:32

标签: c# winforms

我有以下Winforms层次结构。

Form ==> AForm ==> BForm

int? X;中定义了无效成员FormA。在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也不为零。

2 个答案:

答案 0 :(得分:3)

您正在另一个线程上调用代码来测试X(使用AsyncCall和“X ??”),在FormA构造函数中分配X之前或之后可能会运行或不运行代码。

即。如果你停止使用AsyncCall,你应该得到一致的结果。

答案 1 :(得分:2)

在FormA中,X是Nullable int属性,默认为null。您永远不会从public FormA(int? x)构造函数中调用public FormB()基础构造函数,因此X永远不会被设置为其他任何内容。

由于在调用FormB的构造函数(调用AsyncCall)后设置X的值,因此在GetForm函数中设置form.X = x;之前或之后,AsyncCall可能会强制执行时序问题。

如果您希望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();
}