简体   繁体   English

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

[英]Is there a more elegant way to do this in .NET 4.0?

It appears that C# 4.0 does not support covariance (using the "in" keyword) on parameters in overrides; 似乎C#4.0不支持覆盖中的参数的协方差(使用“ in”关键字)。 is that the case? 是这样吗?

If so, is there a more elegant way to do this? 如果是这样,是否有更优雅的方法可以做到这一点?

CONTEXT 语境

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

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

public class MoreDerivedEvent : IDerivedEvent { /* ... */ }

I have a set of classes that handle MoreDerivedEvent . 我有一组处理MoreDerivedEvent的类。 Due to limitations of the event handling code, I can only register a single event handler for MoreDerivedEvent , and I don't know that it will handle registering interfaces as events (I don't believe it will, as the guidance is to use classes explicitly). 由于事件处理代码的限制,我只能为MoreDerivedEvent注册一个事件处理程序,而且我不知道它将把接口注册为事件(我不相信这样做,因为指导是使用类明确地)。 So, in order to handle the event appropriately, I've defined the handlers as follows: 因此,为了适当地处理事件,我将处理程序定义如下:

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

This obviously does not provide true inheritance, and I'll probably just flatten the types derived from DerivedType and BaseType if I can't solve this issue. 这显然不能提供真正的继承,如果我不能解决此问题,我可能只DerivedType平从DerivedTypeBaseType派生的类型。 But I figured I'd put it to the Stack Overflow community first. 但是我认为我会首先将其放入Stack Overflow社区。

First off, parameter type covariance is not typesafe . 首先,参数类型协方差不是typesafe Suppose we allowed parameter type covariance: 假设我们允许参数类型协方差:

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.

No, covariance is not at all what you want. 不, 协方差根本不是您想要的。 It is unsafe. 这是不安全的。 You want covariance on return types , not on parameter types . 您希望在返回类型上而不是参数类型上具有协方差。 On parameter types you want contravariance : 在参数类型上,您需要求

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.

No problem there. 没问题。

Unfortunately for you, C# supports neither return type covariance nor parameter type contravariance. 不幸的是,C#不支持返回类型协方差或参数类型相反方差。 Sorry! 抱歉!

First you need an interface to specify the contra-variance on 首先,您需要一个接口来指定

public interface IBaseHandler<in T> where T : IBaseEvent
{
    void Handle(T handle);
}

Then you can define a base class to do 'base stuff' 然后,您可以定义一个基类来做“基础材料”

public class BaseType<T> : IBaseHandler<T> where T : IBaseEvent
{
    public virtual void Handle(T handle) { /* do base stuff */} 
}

which will then allow you to override for the MoreDerivedEvent 然后将允许您覆盖MoreDerivedEvent

public class MoreDerivedType : BaseType<MoreDerivedEvent>
{
    public override void Handle(MoreDerivedEvent handle)
    {
        base.Handle(handle);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM