C# 3.0 我是否应该支持C#3.0中发布/订阅场景的协变/逆变?
在我的应用程序中,我创建了一个简单的事件中心,它为注册订阅者提供了一些功能:C# 3.0 我是否应该支持C#3.0中发布/订阅场景的协变/逆变?,c#-3.0,covariance,contravariance,publish-subscribe,C# 3.0,Covariance,Contravariance,Publish Subscribe,在我的应用程序中,我创建了一个简单的事件中心,它为注册订阅者提供了一些功能: Subscribes<EventType>(ISubscriber<EventType> subscriber) // and some other methods for adding subscribers 好吧,现在,我想把数据挖掘成这样的“事件类型”。该事件的通用参数必须是协变的 SubX : ISubscriber<DataChanged<A>> Data
Subscribes<EventType>(ISubscriber<EventType> subscriber)
// and some other methods for adding subscribers
好吧,现在,我想把数据挖掘成这样的“事件类型”。该事件的通用参数必须是协变的
SubX : ISubscriber<DataChanged<A>>
DataChanged<T>
T Data {get;}
SubX:ISubscriber
数据更改
T数据{get;}
当我发布publish(newdatachanged(new B())
(给定B:A)时,应该向订阅者通知DataChanged
,其中数据是传递给DataChanged
的B实例。因此,我还需要协方差支持
我想写一个支持协变和逆变的库,如下所示:
IMyObject<T1, T2> : IWithVariance<In, Out>
Obj<Fruit, Fruit> x;
IMyObject<Apple, object> x2 = x.ToVariant<Apple, object>();
IMyObject:IWithVariance
这将允许这样的转换(而不是强制转换!):
IMyObject<T1, T2> : IWithVariance<In, Out>
Obj<Fruit, Fruit> x;
IMyObject<Apple, object> x2 = x.ToVariant<Apple, object>();
Obj-x;
IMyObject x2=x.ToVariant();
你认为呢?有可能吗?考虑过使用动态代理来实现它。在我看来,这会使事情变得非常复杂,而且这意味着你最终会编写大量的反射代码。你能等C#4.0吗?-p 或者,您的代码可以忽略它不知道如何处理的事情…在本部分: 当我发表
发布(新建)
DataChanged(新B())
,则
应向订户
通知
DataChanged
其中。Data
是
B
-实例
我可能不理解你的意思,例如,我看不出。Data
指的是什么,我只能猜测B和A之间的关系。你的意思是B是从A派生出来的吗
如果是这样,C#4不一定会自动发生这样的事情。默认情况下,X
和X
类型根本不兼容。如果X
是一个接口,并且类型参数标记为out
,那么X
可以分配给X
类型的变量。但请注意is仅用于接口,而不是具体类型(对于委托也有类似的规定,但仅此而已)
编辑:
因此,您要做的是模拟X
可以分配给C#/clr4.0中X
类型的变量的方式,其中X是一个接口
假设X是:
interface X<T>
{
T Foo(int arg);
// Note: T may only appear as an output, so this is illegal:
// void Foo(T arg);
}
您只需将每个方法转发到真正的实现
然而,对于泛型外部类和继承相关的泛型参数对的每一个可能组合,您都需要这样一个包装类。手工编写它们并维护一个大的查找来为给定情况选择正确的一个,这将是一个乏味、容易出错且永远无法完成的任务
现在,您进入了代码生成阶段,在运行时生成包装类。您是对的。更正了这个问题。在C#4中,我将以ISubscriber和IChangedEvent结束。对,我必须在这里和那里进行假设。在出现歧义的情况下,我必须抛出异常。
class WrapX_A_B : X<A>
{
public X<B> Impl { get; set; }
public A Foo(int arg)
{
return Impl.Foo(arg);
}
}