In my application I am creating a simple event hub that offers something for registering subscribers:
Subscribes<EventType>(ISubscriber<EventType> subscriber)
// and some other methods for adding subscribers
And for publishing events.
Publish<EventType>(EventType @event)
Quite simple. I want to route Publish<int>(0)
to all subscribers implementing ISubscriber<int>
.
What's not too hard is, that I want the subscribers EventType to be contravariant. So ISubscriber<object>
should basically consume everything. Not shure wether I want them to consume valuetypes, too.
With C#4 that is no problem, but now I'm doing this stuff with C#3 and just faking contravariance with an interface:
public interface IContravariantGenerics {
object AsVariantFor(Type[] genericParamters);
}
Well, now, I want to empack data into "event types" like this. The generic parameters of that events must be covariant.
SubX : ISubscriber<DataChanged<A>>
DataChanged<T>
T Data {get;}
When I publish Publish<DataChanged<B>>(new DataChanged<B>(new B())
(given B : A), the Subscriber should be notified with DataChanged<A>
where Data is the B-instance passed to DataChanged<B>
. So I need covariance support as well.
I thought of writing a lib that supports both Co-/And Contravariance like this:
IMyObject<T1, T2> : IWithVariance<In, Out>
Which would allow conversions (not casts!) like this:
Obj<Fruit, Fruit> x;
IMyObject<Apple, object> x2 = x.ToVariant<Apple, object>();
What do you think? Is it possible? Thought of doing it using dynamic proxies.