我有一本字典如下:
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);
}
答案 0 :(得分: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()
有它们,但希望这些约束相对明显。
答案 1 :(得分:0)
所以你有一个Action<T>
,你需要把它变成Action<object>
。为了做到这一点,如果对象的类型T
不合适,该方法必然会在运行时失败。没有真正的方法。您可以使用DynamicInvoke
尝试使用给定对象调用委托。如果它是正确的类型它将起作用,如果不是,它将不会:
public static Action<object> Foo(Delegate del)
{
return obj => del.DynamicInvoke(obj);
}