作成ロジックを指定するインターフェイスまたは抽象クラスを作成するにはどうすればよいですか?

user1920703

文字列から逆シリアル化できるウィジェットを処理するジェネリッククラスがあります。ジェネリッククラスのインスタンスは、これらのウィジェットの1つのタイプをテンプレートパラメーターとして受け取り、文字列からこれらのウィジェットを作成します。C#のジェネリックの共分散プロパティを使用して、またはでWidgetUser<IWidget>ある可能性のあるオブジェクトを処理するようなコードを記述したいと思います問題は、内部の文字列からウィジェットを作成するために、ガードとして追加する必要があることですこれにより、無効な型になります。現在、私は次のようなコードを持っています:WidgetUser<RedWidget>WidgetUser<BlueWidget>WidgetUser<T>new()WidgetUser<IWidget>

interface IWidget
{
    // Makes this widget into a copy of the serializedWidget
    void Deserialize(string serializedWidget);
}
class WidgetUser<T> where T : IWidget, new()
{
    public void MakeAndUse(string serializedWidget)
    {
        var widget = new T();
        widget.Deserialize(serializedWidget);
        Use(widget);
    }
}

このコードを使用するWidgetUser<BlueWidget>と、がBigWidget満たされるため、問題なく作成できnew()ます。WidgetUser<IWidget>インスタンスIWidget(または同等の抽象クラス)がで動作することが保証されていないため、私は書くことができませんnew()回避策は次のとおりです。

abstract class WidgetUser
{
    public abstract void MakeAndUse();
}

class WidgetUser<T> : WidgetUser
    where T : IWidget, new() 
{ 
    /* same as before but with an 'override' on MakeAndUse */ 
}

このコードを使用して、を処理するWidgetUser<BlueWidget>コードを作成して作成できますWidgetUserほぼ同じことを実現するBaseWidget代わりに、抽象クラスを使用して同様のコードを作成することもできますIWidgetこれは機能的ですが、ダミークラスを定義することを強制しないより直接的なアプローチがあると思います。ダミークラスや追加のファクトリを作成せずに、型システムに意図を伝えるにはどうすればよいですか。「文字列からこれらの1つを作成できます」というインターフェイスが必要です。

TL; DR:文字列からインスタンスを作成できるがnew()、ガードとして必要としないインターフェイスまたは抽象クラスを作成する方法はありますWidgetUser<T>か?

マシューワトソン

ここでの問題は、Deserialize()メソッドが静的メソッドでなければならないということです。したがって、IWidgetそれ自体のメンバーであってはなりません。ファクトリインターフェイスのメンバーであるか、具象ファクトリメソッドから呼び出される具象ウィジェットクラスの静的メンバーである必要があります。後者のアプローチを以下に示します。

(または、Func<IWidget>デリゲートを使用して指定することもできますが、完全なファクトリインターフェイスを提供するのが一般的です。)

したがって、ファクトリインターフェイスを作成することをお勧めします。

interface IWidgetFactory
{
    IWidget Create(string serialisedWidget);
}

次に、Deserialize()からを削除IWidgetます:

interface IWidget
{
    // .. Whatever
}

次に、静的Deserialize()メソッドを次の各具体的な実装に追加しますIWidget

class MyWidget: IWidget
{
    public static MyWidget Deserialize(string serializedWidget)
    {
        // .. Whatever you need to deserialise into myDeserializedObject
        return myDeserializedObject;
    }

    // ... Any needed IWidget-implementing methods and properties.
}

次に、具象ウィジェットクラスの静的Deserialize()メソッドを使用して具象ウィジェットクラスのファクトリを実装します

sealed class MyWidgetFactory : IWidgetFactory
{
    public IWidget Create(string serialisedWidget)
    {
        return MyWidget.Deserialize(serialisedWidget);
    }
}

次に、WidgetUserを受け入れるコンストラクターをクラスに追加し、それを次の場所IWidgetFactoryで使用しMakeAndUse()ます。

class WidgetUser
{
    public WidgetUser(IWidgetFactory widgetFactory)
    {
        this.widgetFactory = widgetFactory;
    }

    public void MakeAndUse(string serializedWidget)
    {
        var widget = widgetFactory.Create(serializedWidget);
        Use(widget);
    }

    private readonly IWidgetFactory widgetFactory;
}

このシナリオでは、のtype引数は不要になったためWidgetUser、削除したことに注意してください

次に、作成するときにWidgetUser、ファクトリを提供する必要があります。

var widgetUser = new WidgetUser(new MyWidgetFactory());

...

widgetUser.MakeAndUse("MySerializedWidget1");
widgetUser.MakeAndUse("MySerializedWidget2");

工場に渡すことで、より多くの柔軟性が得られます。

たとえば、シリアル化スキームに、シリアル化された文字列からウィジェットの種類を判別する方法が含まれていると想像してください。簡単にする目的のために、それはで始まると仮定し"[MyWidget]"、それはだ場合MyWidgetとで始まる["MyOtherWidget"]、それはだ場合MyOtherWidget

次に、次のようにシリアル化文字列を指定して任意の種類のウィジェットを作成できる「仮想コンストラクター」として機能するファクトリを実装できます。

sealed class GeneralWidgetFactory: IWidgetFactory
{
    public IWidget Create(string serialisedWidget)
    {
        if (serialisedWidget.StartsWith("[MyWidget]"))
            return myWidgetFactory.Create(serialisedWidget);
        else if (serialisedWidget.StartsWith("[MyOtherWidget]"))
            return myOtherWidgetFactory.Create(serialisedWidget);
        else
            throw new InvalidOperationException("Don't know how to deserialize a widget from: " + serialisedWidget);

    }

    readonly MyWidgetFactory      myWidgetFactory      = new MyWidgetFactory();
    readonly MyOtherWidgetFactory myOtherWidgetFactory = new MyOtherWidgetFactory();
}

これは一般的に物事を行うための最良の方法ではないことに注意してください-この種のことを管理するには、Autofacなどの依存関係コンテナを使用する方が良いでしょう。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

F#でインターフェイスを継承する抽象クラスを作成するにはどうすればよいですか?

分類Dev

guiceファクトリ支援インジェクトを使用して作成され、抽象クラスから拡張されたクラスのインスタンスを作成するにはどうすればよいですか?

分類Dev

抽象クラスのインスタンスを作成するにはどうすればよいですか?

分類Dev

TClassから作成されたオブジェクトからインターフェイスを取得するにはどうすればよいですか?

分類Dev

wxpythonインターフェースの優れたコンストラクターを作成するにはどうすればよいですか?

分類Dev

typescriptでシンボルインデックスを取得するインターフェイスを作成するにはどうすればよいですか?

分類Dev

@abstractmethodを使用して、コンストラクターの引数構造を指定する抽象インターフェースを作成するにはどうすればよいですか?

分類Dev

SWIGのインターフェースを満たすPythonクラスを作成するにはどうすればよいですか?

分類Dev

SWIGのインターフェースを満たすPythonクラスを作成するにはどうすればよいですか?

分類Dev

プロジェクト内のすべてのフォームのインスタンスを作成するにはどうすればよいですか?

分類Dev

PyQtでジョイスティック/コントローラーウィジェットを作成するにはどうすればよいですか?

分類Dev

Eclipseでカスタムファイル(作成されたプロジェクトごとに作成)を追加するにはどうすればよいですか?

分類Dev

Javaでジェネリッククラスのインスタンスを作成するにはどうすればよいですか?

分類Dev

角度4でタイプインターフェイスのオブジェクトを作成するにはどうすればよいですか?

分類Dev

アンブレラプロジェクトのルートでミックスタスクを作成するにはどうすればよいですか?

分類Dev

ジェネリッククラスインスタンスを特定のインターフェイス内に強制的に適合させる制約を作成するにはどうすればよいですか?

分類Dev

forループ内にクラス(オブジェクト)のインスタンスを作成するにはどうすればよいですか?

分類Dev

オブジェクトのコレクションのインターフェイスを作成するにはどうすればよいですか?

分類Dev

Q&A-厳密に型指定された方法で(インターフェイスまたはクラスの)プロパティ/関数/アクション/メソッドの名前を取得するにはどうすればよいですか?

分類Dev

Q&A-厳密に型指定された方法で(インターフェイスまたはクラスの)プロパティ/関数/アクション/メソッドの名前を取得するにはどうすればよいですか?

分類Dev

変更できないクラスを作成してインターフェイスを実装するにはどうすればよいですか?

分類Dev

異なるクラスに対して1つのインターフェイス実装を作成するにはどうすればよいですか?

分類Dev

その抽象クラスのサブクラスではないインターフェイス実装者をそのインターフェイスの抽象クラスのように動作させるにはどうすればよいですか?

分類Dev

BubbleSortable(インターフェース)オブジェクトにデータを作成して入力するにはどうすればよいですか?

分類Dev

JavaFX 3Dでベクターグラフィックスタイルラインを作成するにはどうすればよいですか?

分類Dev

TypeScript:n個のキーの1つを持つオブジェクト、または文字列であるタイプまたはインターフェイスを作成するにはどうすればよいですか?

分類Dev

インターフェイスnew_with_areaでGtkコンボボックスを作成するにはどうすればよいですか?

分類Dev

ドラッグアンドドロップインターフェイスを作成するにはどうすればよいですか?

分類Dev

ユーザーにインターフェースを公開せずにMoqでモックを作成するにはどうすればよいですか?

Related 関連記事

  1. 1

    F#でインターフェイスを継承する抽象クラスを作成するにはどうすればよいですか?

  2. 2

    guiceファクトリ支援インジェクトを使用して作成され、抽象クラスから拡張されたクラスのインスタンスを作成するにはどうすればよいですか?

  3. 3

    抽象クラスのインスタンスを作成するにはどうすればよいですか?

  4. 4

    TClassから作成されたオブジェクトからインターフェイスを取得するにはどうすればよいですか?

  5. 5

    wxpythonインターフェースの優れたコンストラクターを作成するにはどうすればよいですか?

  6. 6

    typescriptでシンボルインデックスを取得するインターフェイスを作成するにはどうすればよいですか?

  7. 7

    @abstractmethodを使用して、コンストラクターの引数構造を指定する抽象インターフェースを作成するにはどうすればよいですか?

  8. 8

    SWIGのインターフェースを満たすPythonクラスを作成するにはどうすればよいですか?

  9. 9

    SWIGのインターフェースを満たすPythonクラスを作成するにはどうすればよいですか?

  10. 10

    プロジェクト内のすべてのフォームのインスタンスを作成するにはどうすればよいですか?

  11. 11

    PyQtでジョイスティック/コントローラーウィジェットを作成するにはどうすればよいですか?

  12. 12

    Eclipseでカスタムファイル(作成されたプロジェクトごとに作成)を追加するにはどうすればよいですか?

  13. 13

    Javaでジェネリッククラスのインスタンスを作成するにはどうすればよいですか?

  14. 14

    角度4でタイプインターフェイスのオブジェクトを作成するにはどうすればよいですか?

  15. 15

    アンブレラプロジェクトのルートでミックスタスクを作成するにはどうすればよいですか?

  16. 16

    ジェネリッククラスインスタンスを特定のインターフェイス内に強制的に適合させる制約を作成するにはどうすればよいですか?

  17. 17

    forループ内にクラス(オブジェクト)のインスタンスを作成するにはどうすればよいですか?

  18. 18

    オブジェクトのコレクションのインターフェイスを作成するにはどうすればよいですか?

  19. 19

    Q&A-厳密に型指定された方法で(インターフェイスまたはクラスの)プロパティ/関数/アクション/メソッドの名前を取得するにはどうすればよいですか?

  20. 20

    Q&A-厳密に型指定された方法で(インターフェイスまたはクラスの)プロパティ/関数/アクション/メソッドの名前を取得するにはどうすればよいですか?

  21. 21

    変更できないクラスを作成してインターフェイスを実装するにはどうすればよいですか?

  22. 22

    異なるクラスに対して1つのインターフェイス実装を作成するにはどうすればよいですか?

  23. 23

    その抽象クラスのサブクラスではないインターフェイス実装者をそのインターフェイスの抽象クラスのように動作させるにはどうすればよいですか?

  24. 24

    BubbleSortable(インターフェース)オブジェクトにデータを作成して入力するにはどうすればよいですか?

  25. 25

    JavaFX 3Dでベクターグラフィックスタイルラインを作成するにはどうすればよいですか?

  26. 26

    TypeScript:n個のキーの1つを持つオブジェクト、または文字列であるタイプまたはインターフェイスを作成するにはどうすればよいですか?

  27. 27

    インターフェイスnew_with_areaでGtkコンボボックスを作成するにはどうすればよいですか?

  28. 28

    ドラッグアンドドロップインターフェイスを作成するにはどうすればよいですか?

  29. 29

    ユーザーにインターフェースを公開せずにMoqでモックを作成するにはどうすればよいですか?

ホットタグ

アーカイブ