0

次の抽象クラスがあります。

public abstract class BaseClass{
    public object contents { get; set; }
    public Action<BaseClass> mutator;
    public abstract void Initialise();
}

これはいくつかのクラスで使用され、Initializeメソッドをオーバーライドして に値を割り当てます。これは、特定の時点でデリゲートをcontents使用して変更されます。mutator

次の静的クラスがあり、各メソッドは として使用することを目的としていますmutator:

public static class Mutators{
    public static void VariantA(A inputObj){
        // inputObj.contents = something else
    }

    public static void VariantB(A inputObj) { } // etc. etc.
}

次に、BaseClass を実装するクラス A があります。Mutators.VariantA を mutator デリゲートに割り当てようとしていますが、できません。

public class A : BaseClass{
    public A(){
        mutator = Mutators.VariantA;
    }

    public override void Initialise(){
        /* set the value of contents property here */
    }
}

具体的には、次のエラーが発生します: A method or delegateMutators.VariantA(A)' パラメーターがデリゲートと一致しませんSystem.Action<BaseClass>(BaseClass)' parameters (CS0123)

Mutators.VariantA(A)type のオブジェクトが必要Aであり、 Action が type の入力を受け入れるように宣言されていることは理解していますがBaseClass、クラスのA実装として、BaseClassこれを行うことができると思いましたか?

動的に型付けされた言語から来て、この方法で型を操作するのに苦労しています:(

このように抽象型の入力を持つ関数を指す方法はありますか? 他のデザインパターンを見る必要がありますか?

ありがとう

4

2 に答える 2

4

Mutators.VariantA(A) にはタイプ A のオブジェクトが必要であり、アクションはタイプ BaseClass の入力を受け入れるように宣言されていることを理解していますが、クラス A が BaseClass を実装しているため、これを行うことができると思いましたか?

絶対違う。

Anは、任意のオブジェクトAction<BaseClass>を受け入れることができなければなりません。たとえば、あなたのコードが有効であれば、次のように書くことができます。 BaseClass

Action<BaseClass> mutator = Mutators.VariantA;
mutator.Invoke(new B());

B(から派生した別のクラスはどこにありますかBaseClass。)

Bから派生したという事実により、呼び出しBaseClassに対して有効になりますが、メソッドがうまく機能するのには役立ちません。VariantA

ここにミューテーターがある理由ははっきりしていません。そのミューテーターを抽象化する必要があると強く思いますBaseClass。私はあなたが達成しようとしていることをまだ理解していませんが、このデザイン パターンは型安全な方法でそこにたどり着くのに役立ちません。

あなた書くことができます:

public abstract class BaseClass<T> where T : BaseClass<T> {
    public object Contents { get; set; }
    public Action<T> Mutator { get; set; }
    public abstract void Initialise();
}

... それから:

public class A : BaseClass<A> {
    public A() {
        Mutator = Mutators.VariantA;
    }
}

...その場合、「A」値を変更できるものを書いていることになります。しかし、私の経験では、この種の一般的なネスティングは非常に面倒で、非常に迅速に処理されます。

于 2013-04-02T19:11:01.427 に答える
1

現在の例を使用して、クラスの1つのメソッドシグネチャを次のように変更しましたが、機能します

    public abstract class BaseClass
    {
        public object contents { get; set; }
        public Action<BaseClass> mutator;
        public abstract void Initialise();
    }
    public static class Mutators
    {
        public static void VariantA(BaseClass baseClass)
        {
            // inputObj.contents = something else
        }

        public static void VariantB(A inputObj) { } // etc. etc.
    }
    public class A : BaseClass
    {
        public A()
        {
            mutator = Mutators.VariantA;
        }

        public override void Initialise()
        {
            /* set the value of contents property here */
        }
    }
于 2013-04-02T19:13:56.203 に答える