[英]Is there a more elegant way to do this in .NET 4.0?
似乎C#4.0不支持覆蓋中的參數的協方差(使用“ in”關鍵字)。 是這樣嗎?
如果是這樣,是否有更優雅的方法可以做到這一點?
語境
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
平從DerivedType
和BaseType
派生的類型。 但是我認為我會首先將其放入Stack Overflow社區。
首先,參數類型協方差不是typesafe 。 假設我們允許參數類型協方差:
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 */}
}
然后將允許您覆蓋MoreDerivedEvent
public class MoreDerivedType : BaseType<MoreDerivedEvent>
{
public override void Handle(MoreDerivedEvent handle)
{
base.Handle(handle);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.