1

ここでは、EditMyDataObjectプロパティを設定した基本形式と、Text値を取得して後で復元する拡張形式で、Resharperの警告が表示されます。

どちらの場合も、アプリを実行しても何も起きません。私のオーバーライドされたプロパティはコンストラクタで初期化されたものには依存しないので、実装されたときに問題が発生する可能性はないと思いますが、Resharperをギャグする前にセカンドオピニオンをいただければ幸いです。

public class MyDataObject
{
    //Data Members

    public MyDataObject()
    {
    }
}

public class MyDataObjectEx : MyDataObject
{
    //Data Members

    public MyDataObjectEx()
    {
    }

    public MyDataObjectEx(MyDataObject myDataObject)
    {
    }       
}

public partial class MyDataObjectEditFrm : Form
{
    private MyDataObject _myDataObject;

    protected virtual MyDataObject EditMyDataObject
    {
        get { return _myDataObject; }
        set { _myDataObject = value; }
    }

    /// <summary>
    /// Parameterless constructor needed for designer support of derived classes.
    /// </summary>
    protected MyDataObjectEditFrm()
    {
        InitializeComponent();
    }

    protected MyDataObjectEditFrm(MyDataObject myDataObject)
    {
        InitializeComponent();
        EditMyDataObject = myDataObject;  // Warning: Virtual member call in a constructor

        Text = GetDialogNameFromInputParameters()

        //Remainder of initialization here
    }

    GetDialogNameFromInputParameters()
    {
        //Figure out what the text should be
    }
}


public partial class MyDataObjectExEditFrm : MyDataObjectEditFrm
{
    private MyDataObjectEx _myDataObjectEx;

    protected override MyDataObject EditMyDataObject
    {
        get { return _myDataObjectEx; }
        set
        {
            if (value == null)
                _myDataObjectEx = null;
            else _myDataObjectEx = value as MyDataObjectEx ?? new MyDataObjectEx(value);
        }

    }

    public MyDataObjectExEditFrm(MyDataObject myDataObject) : base(myDataObject)
    {
        //preserve the value computed and set in the base class to prevent the generic form name from the designer overriding it here
        string dialogText = Text; // Warning: Virtual member call in a constructor
        InitializeComponent();
        Text = dialogText; // Warning: Virtual member call in a constructor


        //Remainder of additional initialization for extended data here
    }
}


  • 編集:間違っている、ありがとうダニエル必要に応じて、propertyの代わりに基礎となる変数を設定することで最初の警告を取り除くことができます。私はこれが良い考えであるかどうかについて意見を持っていません、私はただ言っています。 - jv42
  • @ jv42:それは行動を変えるでしょう。オーバーライドされたプロパティを見てください、それはそれにいくつかのロジックを持っています... - Daniel Hilgarth
  • @ vj42:試したことがあると思いますが、MyDataObjectExに変換されていないため、MyDataObjectExEditFormに基本のMyDataObjectしか渡されなかった場合に問題が発生しました - Dan Neely
  • 申し訳ありませんが、派生クラスで実際にオーバーライドしていたという事実を見逃していました。 - jv42
  • あなたはいつでも仮想呼び出しを抽象メソッドにパイプすることができます。そして、それはどんな派生クラスもこの抽象メソッドを実装することを強制します。これは、クラスがメソッドを実装しないことは不可能であることを意味します。つまり、継承したクラスに欠けているメソッドでエラーが発生することは決してあり得ません。この未来はあなたのクラスを証明します。 - Contango

1 답변


6

派生クラスのコンストラクタで初期化された変数に依存しないように、各派生クラスがこの仮想メンバーをオーバーライドする限り、安全です。問題は、基本クラスから派生したすべてのクラスがこのように動作することを知ることができないということです。そのため、警告は合法です。


  • 私は将来事態を悪化させる可能性があることを知っていました。ただし、公共図書館ではないため、機能を損なうことなくデザインを変更できない場合は、危険性を管理することができます。 - Dan Neely

関連する質問

最近の質問