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 回答