2012-06-08 51 views
1

我有以下Winforms層次結構。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永遠不會被指定爲零或零。我正試圖關閉並打開表格FormB。偶爾z是零(也許每10次一次)。我設置了一個條件中斷,當z==0在線return z上時中斷。

當中斷點被擊中時。調試寫入

X: z: 0 

即使調試顯示FormA:X不爲零。

+0

現在很明顯。您正在調用FomrB構造函數(它會啓動您的AsyncCall)。你*然後*調用'form.X = x;'。取決於AsyncCall完成的速度,它在處理X時可能有也可能沒有值。 –

回答

3

您正在調用另一個代碼d來測試X(使用AsyncCall和「X ??」),該代碼可能會或可能不會在FormA構造函數中分配X之前或之後運行。

即,如果你停止使用AsyncCall,你應該得到一致的結果。

2

在FormA中,X是一個Nullable int屬性,默認爲null。你永遠不會從你的public FormB()構造函數調用public FormA(int? x)基構造函數,所以X永遠不會被設置爲其他任何東西。

由於您在調用FormB的構造函數(它調用AsyncCall)之後設置X的值,您將遇到計時問題,因爲在您的GetForm函數中設置form.X = x;之前或之後,AsyncCall可能會強制執行。

如果你希望你的AsyncCall仍然是一個AsyncCall,你應該更新FormB()的構造函數如下:

公共FormB(INT X):基材(X) {// ...

,然後更新GetForm如下(注意where子句,這讓我們知道T是至少從FROMA衍生的,所以它有一個構造函數中的一個int):

public static T GetForm<T>(int? x) where T : FormA 
{ 
    T form = new T(x); 
    form.Show(); 
} 
+0

我更新了問題。我確實叫過'新的FormB(100)'。 – ca9163d9

+0

你的'FormB(int)'構造函數在哪裏?它沒有在上面的代碼中列出,它可能不會調用你的無參數FormB()構造函數,或者它不調用基構造函數。 –

+0

我已更新該問題。表單使用靜態方法創建。 – ca9163d9