4

プロジェクトに複数の Form クラスが必要です。そこで、これらのフォームに共通するすべてのものを抽象クラスにまとめることを考えていました。このクラスには、フォーム クラスとインターフェイスが継承されます。そのようなもの:

public interface IMyForm
{
void Init();
}

public abstract class AMyForm : Form, IMyForm
{
    void IBrowser.Init()
    {
        throw new NotImplementedException();
    }     
}

public partial class MainClass : AMyForm 
{

// But here the warning is shown (That i have to add override keyword),
// but when i do, The error is shown that i cannot override from non abstract thing 
    public void Init() 
    {
    }
}

それを達成する方法を教えていただけますか?

4

3 に答える 3

8

Jon Skeetsの回答は一般的なプログラミングでは正しいですが、フォームとユーザーコントロールで抽象クラスを使用することはお勧めしません。最初の問題は、デザイナーが抽象クラスのインスタンスを作成できないため、デザイナーで抽象フォームから継承するフォームを表示できないことです。以下のコメントで提案されているように、抽象クラスを実装し、他の継承されたフォームのベースとして使用されるサロゲート クラスを追加しない限り、デザイナーを介して新しいコントロールをフォームに追加できないことを意味しますAbstractMyForm -> MyFormSurrogate -> MyForm

2番目の大きな問題は、私の意見では、これはロジックをフォームに貼り付けようとしていることを意味します. これは通常、望ましくありません。特に、ビジネス ロジックをディスプレイ テクノロジに結合する場合 (この場合は特に) ですWinforms。私のアドバイスは、モデル ビュー プレゼンター パターンを使用して、通常のクラス (抽象クラス、インターフェイスなどを使用) でできるだけ多くのロジックを分離し、それらをフォームにデータ バインドすることです。共有されているビジュアル パーツ (チェック ボックスのグループなど) がある場合は、そのようなパーツのユーザー コントロールを作成し、フォームで再利用します。

winform の操作に関する知識をあまり想定していないことを願っていますが、GUI 開発を始めたときに同様の質問がありました。

于 2012-07-16T20:53:04.783 に答える
7

抽象クラスで明示的なインターフェイス実装を使用したくないだけです。

public abstract class AMyForm : Form, IMyForm
{
    public virtual void Init()
    {
        throw new NotImplementedException();
    }     
}

または単に抽象化してください:

public abstract class AMyForm : Form, IMyForm
{
    public abstract void Init();
}

どちらの場合も、具象クラスでオーバーライドするだけです。

または、抽象クラスで明示的なインターフェイス実装を本当に使用したい場合は、具象クラスで再度使用する必要があります。

public partial class MainClass : AMyForm, IMyForm
{
    void IMyForm.Init() 
    {
        // Stuff
    }
}

欠点は、AMyFormこれを行わないIMyFormサブクラスは基本的に実装が壊れていることです。ここでは、最初のアプローチを使用することをお勧めします。

編集:または、スーパーキャットの提案に従って:

public abstract class AMyForm : Form, IMyForm
{
    void IBrowser.Init()
    {
        InitImpl();
        // And anything else you need...
    }     

    // Or abstract...
    protected virtual void InitImpl()
    {
    }
}

InitImpl次に、具象クラスでオーバーライドします。

于 2012-07-16T16:09:10.457 に答える
3

抽象クラスがデザイン ビューに表示されない。コンパイラのifステートメントを抽象クラスに追加して、設計時に抽象化しないようにすることで、これを回避できます。

#if RELEASE
    public abstract class AbstractForm : Form, IInterface
#else
    public class AbstractForm : Form, IInterface
#endif
    {
        // Your abstract code here.
    }

これは、非常に効果的に機能する素敵な小さなハックです。同じトリックを使用して、設計時と実行時に仮想メソッドと抽象メソッドを切り替えることができます。

補遺:

抽象形式を使用する必要がないことに注意してください。非抽象フォームから継承する方が効率的であり、潜在的な問題が発生する可能性が低くなります。

public partial class Screen : Form, IInterface
{
    // Base Class here, complete with .designer.cs and .resx
    public Screen()
    {
        InitialiseComponent();
    }

    #region IInterface imported methods
    public partial void SomeMethod()
    {
        // Do something.
    }
    #endregion
}

次に、たとえばログオン画面を作成する場合は、次のようにします。

public partial class LogonScreen : Screen, IInterface
{
    // Derived Class here, complete with .designer.cs and .resx
    public Screen()
    {
        InitialiseComponent();
    }

    #region IInterface imported methods
    public partial void SomeMethod()
    {
        // Do more somethings!
    }
    #endregion
}
于 2013-01-29T01:46:36.903 に答える