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