.NET 4.0中有更好的方法来做到这一点吗?
似乎C#4.0不支持覆盖参数中的协方差(使用“in”关键字);是这样吗?.NET 4.0中有更好的方法来做到这一点吗?
如果是这样,有没有更好的方法来做到这一点?
背景
public interface IBaseEvent { /* ... */ }
public interface IDerivedEvent : IBaseEvent { /* ... */ }
public class MoreDerivedEvent : IDerivedEvent { /* ... */ }
我有一组处理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);
}
}
这显然并不提供真正的继承,我可能就拼合从DerivedType
和BaseType
如果我得到的类型无法解决这个问题。但我想我会先把它放到Stack Overflow社区。
首先,参数类型协方差是不是类型安全的。假设我们允许的参数类型的协方差:
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.
没有,协方差是不是所有你想要的。这是不安全的。你想要协方差返回类型,而不是参数类型。在参数类型,你想逆变:
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.
没问题的。
不幸的是,C#不支持返回类型协方差和参数类型的逆变。抱歉!
首先,你需要一个接口来指定
public interface IBaseHandler<in T> where T : IBaseEvent
{
void Handle(T handle);
}
逆动方差然后你就可以定义一个基类做“基地东西”
public class BaseType<T> : IBaseHandler<T> where T : IBaseEvent
{
public virtual void Handle(T handle) { /* do base stuff */}
}
那么这将让你重写for MoreDerivedEvent
public class MoreDerivedType : BaseType<MoreDerivedEvent>
{
public override void Handle(MoreDerivedEvent handle)
{
base.Handle(handle);
}
}
+1 - 这是一个有趣的方法。在这种情况下,我不喜欢它,因为它引入了一个不会被使用的接口,根据定义,我的受保护的方法将会公开。 – arootbeer 2010-11-10 03:46:44
感谢修改co-versus contravariance;我已经更新了问题和标签。 – arootbeer 2010-11-10 03:37:50