2013-10-15 59 views
2

我有如下的字典:你如何動態地動作動作類型<T>?

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); 
} 
+2

'evt.Subscribe'方法的簽名是什麼? –

+0

訂閱方法得到一個動作 MaYaN

+4

然後,你可能需要改變你的字典是'Dictionary >'類型。除非你可以改變這種方法。 –

回答

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()有他們,但希望這些會比較明顯。

0

所以,你有一個Action<T>,你需要把它變成一個Action<object>。爲了做到這一點,如果對象不是正確的類型T,那麼該方法必然會在運行時失敗。沒有真正的解決方法。您可以使用DynamicInvoke嘗試調用具有給定對象的委託。如果這是正確的類型,將工作,如果它不是,它不會:

public static Action<object> Foo(Delegate del) 
{ 
    return obj => del.DynamicInvoke(obj); 
}