私はイベントシステムを作成していますが、さまざまなジェネリック型のイベントを保存しようとしたときに障害が発生しました。
イベントは次のように定義されます。
public delegate void EventHandler<EventInfo>(object sender, EventInfo eventInfo) where EventInfo : IEventInfo;
public interface IEventInfo { }
public interface IEvent<EventInfo> where EventInfo : IEventInfo
{
void Publish(object sender, EventInfo e);
void Subscribe(EventHandler<EventInfo> evtHandler);
void Unsubscribe(EventHandler<EventInfo> evtHandler);
}
public class Event<EventInfo> : IEvent<EventInfo> where EventInfo : IEventInfo
{
private event EventHandler<EventInfo> eventHandler;
public void Publish(object sender, EventInfo e)
{
if (eventHandler != null)
eventHandler(sender, e);
}
public void Subscribe(EventHandler<EventInfo> evtHandler)
{
this.eventHandler -= evtHandler;
this.eventHandler += evtHandler;
}
public void Unsubscribe(EventHandler<EventInfo> evtHandler)
{
this.eventHandler -= evtHandler;
}
}
このモデルはサブスクライブと公開に機能するようですが、独自のイベントクラスを実装した主な理由は、イベントアグリゲーターで使用できるようにするためであり、コンポーネントを分離できます。
public class EventAggregator
{
private IDictionary<Type, IEvent<IEventInfo>> dictionary;
public EventAggregator()
{
this.dictionary = new Dictionary<Type, IEvent<IEventInfo>>();
}
public EventType GetEvent<EventType>() where EventType : class, IEvent<IEventInfo>, new()
{
IEvent<IEventInfo> evt;
Type evtType = typeof(EventType);
if (!dictionary.TryGetValue(evtType, out evt))
dictionary[evtType] = evt = new EventType();
return evt as EventType;
}
}
上記の関数は、派生EventInfo
クラスでは機能しません。例えば:
public class FooEventInfo : IEventInfo { }
public class FooEvent : Event<FooEventInfo> { }
EventAggregator ea = new EventAggregator();
var x = ea.GetEvent<FooEvent>(); // Error 3: The type 'TestEvent' cannot be used as type parameter 'EventType' in the generic type or method 'EventAggregator.GetEvent<EventType>()'. There is no implicit reference conversion from 'TestEvent' to 'IEvent<IEventInfo>'.
、、を考えるとTestEvent : Event<TestEventInfo>
、なぜこのキャストは失敗するのですか?Event<TestEventInfo> : IEvent<TestEventInfo>
TestEventInfo : IEventInfo