2

私は以下のような辞書を持っています:

var composEvents = new Dictionary<Type, Delegate>
{
    { 
        typeof (GetWorkflowAnalysisDealLevelViewDataCompletedEvent),
        new Action<bool>(GetWorkflowAnalysisDealLevelViewDataCompleted)
    },{
        typeof (NoDataReturnedEvent), 
        new Action<NoDataReturnedParameters>(NoDataReturned)
    }
};

次に、アクションをコールバックとして渡すさまざまなイベントにサブスクライブしていますが、各アクションのタイプはイベントごとに異なるため、次のようになります。

 Action<bool>
 Action<NoDataReturnedParameters>

アクションタイプを明示的にキャストせずに、以下のコードを動的に生成するにはどうすればよいですか?

foreach (var cEvent in composEvents)
{
    var method = typeof(IEventAggregator).GetMethod("GetEvent", BindingFlags.Public | BindingFlags.Instance);
    var generic = method.MakeGenericMethod(cEvent.Key);
    dynamic evt = generic.Invoke(_eventAggregator, null);
    var cancelationToken = evt.Subscribe((Action<bool>)cEvent.Value);
    _compositeEvents.Add(evt, cancelationToken);
}
4

2 に答える 2

1

次の方法で意図した結果が得られると思います。

public abstract class Base 
{
    public abstract void Assign ( object value );
}

public class Assigner<EventType, ActionType>: Base
{
    public override void Assign ( object value )
    {
        AssignAction((ActionType)value);
    }

    private void AssignAction ( ActionType action )  
    {
        var event = _eventAggregator.GetEvent<EventType>();
        var token = event.Subscribe(action);
        _compositeEvents.Add(event, token);
    }
}

何処か別の場所:

foreach (var cEvent in composEvents)
{
    var genericType = typeof(Assigner<,>).MakeGenericType(cEvent.Key, cEvent.Value.GetType());
    var assignerInstance = (Base)Activator.CreateInstance(genericType);
    assignerInstance.Assign(cEvent.Value);
}

すべてのコードをここに直接入力したので、構文エラー、タイプミス、偶発的な誤指示がある可能性があることに注意してください。

そうでない場合でも、うまくいくと思います。お気軽にお知らせください。

このAssigner型は、アクセスできない (ほとんどの場合) _compositeEvents と _eventAggregator を使用しているため、それらをコンストラクターに渡すか、どこかからアクセスできるようにする必要があります。

いくつかの制約をジェネリック型パラメーターに追加する必要がありますが、GetEvent()これらは比較的明白であることを願っています。

于 2013-10-15T18:24:52.857 に答える
0

したがって、 がAction<T>あり、それを に変換する必要がありますAction<object>。これを行うために、オブジェクトが適切なタイプでない場合、メソッドは実行時に必然的に失敗しますT。それを回避する本当の方法はありません。を使用DynamicInvokeして、指定されたオブジェクトでデリゲートを呼び出すことができます。正しいタイプの場合は機能しますが、そうでない場合は機能しません。

public static Action<object> Foo(Delegate del)
{
    return obj => del.DynamicInvoke(obj);
}
于 2013-10-15T16:50:11.550 に答える