在.NET 4.0中有更优雅的方法吗?

aro*_*eer 1 c# overriding .net-4.0 contravariance

似乎C#4.0不支持覆盖中参数的协方差(使用"in"关键字); 那是这样吗?

如果是这样,有没有更优雅的方式来做到这一点?

CONTEXT

public interface IBaseEvent { /* ... */ }

public interface IDerivedEvent : IBaseEvent { /* ... */ }

public class MoreDerivedEvent : IDerivedEvent { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

我有一组处理的类MoreDerivedEvent.由于事件处理代码的限制,我只能注册一个事件处理程序MoreDerivedEvent,我不知道它会将接口注册为事件(我不相信它会,因为指导是明确使用类).因此,为了适当地处理事件,我已经定义了处理程序如下:

public class BaseType
{
    protected virtual void Handle(IBaseEvent @event) { /* Do Base Stuff */ }
}

public class DerivedType
{
    protected virtual void Handle(IDerivedEvent @event)
    {
        /* Do Derived Stuff */
        Handle((IBaseEvent)@event);
    }

    protected override sealed void Handle(IBaseEvent @event)
    {
        base.Handle(@event);
    }
}
Run Code Online (Sandbox Code Playgroud)

这显然不提供真正的继承,我可能只是压缩派生的类型DerivedType,BaseType如果我不能解决这个问题.但我想我先把它放到Stack Overflow社区.

Eri*_*ert 7

首先,参数类型协方差不是类型安全的.假设我们允许参数类型协方差:

class B 
{
    public virtual void Frob(Animal a)
    {
    }
}
class D : B
{
    public override void Frob(Giraffe g)
    {
    }
}
....
B b = new D();
b.Frob(new Tiger());  // Calls D.Frob, which takes a giraffe.
Run Code Online (Sandbox Code Playgroud)

不,协方差根本不是你想要的.这是不安全的.您希望返回类型的协方差,而不是参数类型.在参数类型上你想要逆变:

class B 
{
    public virtual void Frob(Giraffe g)
    {
    }
}
class D : B
{
    public override void Frob(Animal a)
    {
    }
}
....
B b = new D();
b.Frob(new Giraffe());  // Calls D.Frob, which takes any animal.
Run Code Online (Sandbox Code Playgroud)

没问题.

不幸的是,C#既不支持返回类型协方差也不支持参数类型逆变.抱歉!