0

このようなメソッド シグネチャがあるとします。

public void Execute(Action<T> action) {
    ...
}

しかし、提供された「アクション」がクラス「MyActions」からのみ取得されるように制約したいのですが、これを c# でどのように実現できますか?


より明確にするために;

たとえば、MyActions というクラスがあります。

public class MyActions {
    public void FirstAction<T>(T item) {
        ...
    }

    public void SecondAction<T>(T item) {
        ...
    }
}

私は上記のメソッドを持っていますが、メソッドが受け入れる唯一のアクションがこのクラスからのものであるようにしたいです。

誰でも任意のアクションを提供できるようにしたくありません。クラス 'MyActions' から取得する必要があります。

それはできますか?

よろしく、

ライアン。

4

4 に答える 4

2

のメンバーのみを受け入れたいという意図を明確にする 1 つの方法は、次のMyActionsようになります。

public void Execute(Func<MyActions, Action<T>> actionSelector)

その後、次のように呼び出すことができます

Execute(actions => actions.SomeAction);

もちろん、これはメソッド (またはデリゲート プロパティ)MyActionsが静的でない場合にのみ機能します。

そして、私が言ったように、これはあなたの意図を明確にしますが、実際にはメソッドを制約しません.誰かがあなたのメソッドを次のように呼び出すことができます:

Execute(ignored => otherAction);

一般的に、これは奇妙なことのように思えます。

于 2012-05-05T00:25:54.683 に答える
1
public sealed class MyActions <T> where T:new()
{ 
    public enum Methods { First, Second }  

    static Action<T>[] MethodsArray = { Method1, Method2 };
    public virtual void Execute(T value, Methods methods = Methods.First)
    {
        MethodsArray[(int) methods].Invoke(value);
    }
    private void Method1(T value) {}
    private void Method2(T value) {}

}

//public class MiActionsSeconds<T> : MyActions <T>    where T:new()
// {
//     public override void Execute( T value, Methods methods = Methods.Second )
//     {
//         base.Execute( value, methods );
//     }
// }

public class Foo<T>  where T:new()
{
    public void Execute(MyActions<T> instance, MyActions<T>.Methods methods = Methods.First)
    {
        instance.Execute( default( T ) );
        instance.Execute( default( T ), MyActions<T>.Methods.Second );
    }

    public void Test()
    {
      //  Execute( new MiActionsSeconds<T>( ) );
    }
}
于 2012-05-05T00:17:08.637 に答える
1

Reflectionを使用してこれを行うことはできますが、パフォーマンスが低下する可能性があります。これは単なる悪い考えであるため、お勧めしません。あまり具体的でない質問を試してみるべきだと思います。あなたが達成したいことを私たちに伝えて、それがあなたをこの道に導いたのはどうですか、そして多分私たちはあなたがそれを別の方法で達成するのを助けることができます。

于 2012-05-05T00:19:33.647 に答える
0

これに関する大きな問題は、一度Action<...> foo = MyActions.FirstAction渡すExecuteと値を取得したことになり、その型は単にAction<...>. 以前に の参照に格納されていたことを示す型には何もありませんMyActionsMyActions参照を比較することで、渡されたアクションが含まれているかどうかを確認できますが、それはランタイム チェックです。

この情報を型に入れる部分的な方法は、MyActionすべてがMyActions派生するクラスを持つことです。Execute次に、インスタンスの取得を制限できMyActionます。ただし、ユーザーは独自のMyActionサブクラスを作成するのと同じくらい簡単に作成できます。

これは、内部の不必要な公開のような匂いがします: その小さなセットの のみがAction機能する場合、なぜユーザーに ? を要求するのActionですか? enumユーザーがインテントを指定できるようにするか、いくつかの異なるメソッドを指定できるようにExecuteする方が理にかなっています。

于 2015-08-30T16:09:22.443 に答える