1

次の Winforms 階層があります。

Form ==> AForm ==> BForm

int? X;そして、 で定義された null 許容メンバーがあります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);

Xnull または 0 が割り当てられることはありませんでした。フォームを閉じて開こうとしていFormBます。ゼロzの場合もあります (10 回に 1 回程度)。z==0ライン上でブレークする条件付きブレークを設定しましたreturn z

ブレークポイントにヒットしたとき。デバッグ書き込み

    X:  z: 0

デバッグでも FormA:X がゼロではないことを示しています。

4

2 に答える 2

3

別のスレッドでコードを呼び出して X をテストし (AsyncCall と "X ??" を使用)、そのコードは FormA コンストラクターで X が割り当てられる前または後に実行される場合と実行されない場合があります。

つまり、AsyncCall の使用をやめれば、一貫した結果が得られるはずです。

于 2012-06-08T19:15:24.720 に答える
2

FormAでは、XはNullable intプロパティであり、デフォルトはnull。です。public FormA(int? x)コンストラクターから基本コンストラクターを呼び出すことは決してないpublic FormB()ので、Xが他のものに設定されることはありません。

FormBのコンストラクター(AsyncCallを呼び出す)を呼び出した後にXの値を設定しているため、GetForm関数で設定する前または後にAsyncCallが強制される可能性があるため、タイミングの問題が発生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();
} 
于 2012-06-08T18:47:17.427 に答える