0

私は立ち往生しています、なぜこれが機能しないのですか?

  var childAction = new Action<CancelCommand>(blabla);
  Action<IDomainCommand> upperAction = (Action<IDomainCommand>) childAction;

CancelCommandがIDomainCommandを実装している場合、なぜこれが機能しないのですか?ちなみに、この共変性と反変性は私がここでやろうとしていることですか?;)

最高のローリンだけを事前にありがとう

編集 あなたの非常に速い応答をありがとうみんな!

これが必要な理由は、汎用のアクションテンプレートを作成するためです。私は次のインターフェースを持っています:

IMessageBus.RegisterAction<T>(Action<T> registerAction) where T : IDomainCommand

実行時にこのアクションを作成する必要があるため、コードは次のようになります。

var genericExecuteAction = this.GetType().GetMethod("ExecuteCommandAction",
                                                            BindingFlags.NonPublic | BindingFlags.Instance).MakeGenericMethod(commandType);

var actionType = typeof(Action<>).MakeGenericType(commandType);
var @delegate = Delegate.CreateDelegate(actionType, this, genericExecuteAction);
var actionDelegate = (Action<DomainCommandBase>)@delegate;

messageBus.Register(actionDelegate);

問題は、このメソッドに渡すことができるようにキャストする必要があることです。分かりますか?私たちが使用しているメッセージバスの背後ではRXを使用していますが、残念ながら、そこで使用されているすべてのメソッドでジェネリックが使用されており、現在はジェネリックではないオーバーロードが発生しています。

4

4 に答える 4

1

のタイプパラメータは反変です。明らかに、任意のオブジェクトで機能するメソッドが文字列でも機能するため、をにAction割り当てることができます。Action<object>Action<string>

ここで行うことは、CancelCommand(派生型)で機能するメソッドを、任意のIDomainCommand(基本型)で機能するメソッドとして請求しようとしています。これは論理的に間違っているので、コンパイラはそれを許可しません-もしそうなら、あなたはそれをupperAction渡すことを呼び出すことができますDifferentTypeOfDomainCommand

于 2012-09-26T09:09:23.327 に答える
0

これは反変性です。これは機能していません。これが可能であれば、次のように書くことができるからです。

interface IDomainCommand { }
class CancelCommand : IDomainCommand { }
class AcceptCommand : IDomainCommand { }

        Action<CancelCommand> a1 = c => { };
        Action<IDomainCommand> a2 = a1;

        var acceptCommand = new AcceptCommand();

        a2(acceptCommand); // what???

a2を指しa1、a1は。AcceptCommandではないため、引数を受け入れることができませんCancelCommand

于 2012-09-26T09:09:57.053 に答える
0

ちょっと待ってください、なぜこれを機能させたいのですか?

あなたchildActionはを受け入れ、CancelCommandそれを使って何かをするものです。

ただし、だけでなく、任意upperActionので呼び出すことができます。上記をコンパイルしたと仮定します。私がやったときに何が起こるべきか IDomainCommandCancelCommand

upperAction(new EditCommand());

ここでclass EditCommand : IDomainCommand

逆に割り当てを試みる場合:

        var upperAction = new Action<IDomainCommand>(idc => { });
        Action<CancelCommand> childAction = upperAction;

それは機能し、キャストも必要ありません。すべてAction<IDomainCommand>がとしてカウントされますAction<CancelCommand>

于 2012-09-26T09:10:38.787 に答える
0

これらのデリゲートがどのように使用されているかを忘れている

var childAction = new Action<CancelCommand>(blabla);
Action<IDomainCommand> upperAction = (Action<IDomainCommand>) childAction;

upperAction将来のある時点で呼び出され、何らかの形のIDomainCommandオブジェクトを渡すことを意味します。オブジェクトのみを処理できる関数を与えていCancelCommandます。しかし、(おそらく) を実装する他のクラスがありIDomainCommandupperActionそれらのいずれかで呼び出される可能性があります。

于 2014-08-22T14:46:05.560 に答える