0

そんなクラスがあります。

public class Step<T>
{
    public delegate void Act<T>();

    Act<T> _act;

    public Step(Act<T> action)
    {
        Contract.Requires(action != null);

        _act = action;
    }

    public void PerformStep()
    {
        _act.Invoke();
    }
}

私の問題は次のとおりです。このクラスのコンストラクターが、クラスに表示される定義を持つデリゲートを受け入れることができるようにしたいと考えています。私が望んでいないのは、そのデリゲートが私のクラスのパブリック メンバーになることです。これに代わる方法は、クラスの外部にパブリックデリゲートを持ち、他のクラスは必要としませんが、このクラスはそれを必要とすることです。デリゲートを非公開にする方法はありますか?

その解決策が不可能な場合、代替手段はありますか? このステップ クラスは、順次実行されるデリゲートの単なるラッパーです。より一般的な解決策があれば、署名は必要ありません。

編集: 明確化のための詳細情報。

このクラスの目的は、ユーザーが次のようなことを行えるようにすることです。

クラスカーがあれば。この車には、Drive、Stop、Turn などのメソッドがあります。この Step クラスを使用すると、クラスのユーザーはクラスのインスタンスを作成して、次のことを実行できるはずです。

Car c = new Car();
Step<Car> step1 = new Step<Car>(c.TurnLeft);
Step<Car> step2 = new Step<Car>(c.Drive);
Step<Car> step3 = new Step<Car>(c.TurnRight);
//add steps to a collection
c.AddNewRoutine(collection of steps);
c.RunRoutine(identify which routine);

ステップは、順番に実行できるようにするデータ構造に追加されます。car クラスには、これらのステップのグループを保持できるデータ構造が含まれます。これにより、任意のクラスを作成し、クラスまたはメイン プログラムで動作をハードコーディングすることなく、そのクラスが実行する手順をユーザーに設定させることができます。

終わる。ステップクラスをそのままにする必要があります。それを必要とする唯一のクラスは Step クラスであるため、どのような形式でもそのデリゲートへのパブリックアクセスを許可したくありません。

4

3 に答える 3

2

他のクラスがデリゲートを使用する必要がある場合は、それを公開する必要があります。限目。

唯一の実際のオプションは、コンストラクターがそのデリゲート型に変換できる他の種類のパラメーターを受け入れるコンストラクターを追加することです。

于 2013-02-04T16:35:40.310 に答える
2

この例では、パラメーターをとらず、戻り値を持たないカスタム デリゲートを使用しています。これにSystem.Actionは が理想的かもしれません。カスタム デリゲートが戻り値を提供する必要がある場合は、System.Func代わりに使用します。

http://msdn.microsoft.com/en-us/library/system.action.aspx

http://msdn.microsoft.com/en-us/library/bb534960.aspx

提供したサンプルから、必要なものは次のようになります。

public class Step<T>
{
    Action _action;

    public Step(Action action)
    {
        Contract.Requires(action != null);

        _action = action;
    }

    public void PerformStep()
    {
        _action.Invoke();
    }
}
于 2013-02-04T16:38:57.277 に答える
1

デリゲートをまとめて削除し、アクションを使用します。

private Action<T> _action;

public Step(Action<T> action)
{
   _action = action;
}

編集:

System.Action型パラメータのない単純なものを使用することもできます

private Action _action;

public Step(Action action)
{
   _action = action;
}

ただし、これを行うときは次の点に注意してください。

var c = new Car();
var step1 = new Step(c.TurnLeft);

step1 を実際のインスタンスに結び付けている場合c、そのステップを別のインスタンスに再利用することはできません。

var c2 = new Car(); //There's no way to call step1 on this =(
于 2013-02-04T16:36:39.273 に答える