[英]C# Covariance and Contravariance
我有類Message1D
和Message2D
都繼承自Message
:
public abstract class Message {}
public class Message1D : Message {}
public class Message2D : Message {}
實現它的接口IFoo
和類Bar
和Baz
:
public interface IFoo<out G, in T>
where G : Message
where T : Message
{
G PassMessage(T input);
}
public class Bar : IFoo<Message1D, Message1D>
{
public Message1D PassMessage(Message1D input)
{
throw new NotImplementedException();
}
}
public class Baz : IFoo<Message2D, Message2D>
{
public Message2D PassMessage(Message2D input)
{
throw new NotImplementedException();
}
}
我的問題在這里。 如何將Foo和Bar實例添加到列表中?
public class Network
{
private List<IFoo<Message, Message>> messages = new List<IFoo<Message, Message>>();
public void AddBar()
{
messages.Add(new Bar());
}
public void AddBaz()
{
messages.Add(new Baz());
}
}
我有一個例外:
無法將
Bar
轉換為IFoo<Message,Message>
和
無法將
Baz
轉換為IFoo<Message,Message>
如何將Bar
和Baz
實例添加到列表中?
如何將Bar和Baz實例添加到列表中?
你不能,因為你試圖將輸入消息視為協變,但它是逆變的。 您可以將IFoo<Message1D, Message>
視為IFoo<Message, Message>
,但不能將IFoo<Message, Message1D>
視為IFoo<Message, Message>
。 如果這是有效的,那么將允許某人將2D消息傳遞到只能處理1D消息的對象中。
正如@Servy所提到的,在您當前的架構中是不可能的,您應該重新制作它。
但是如果你能保證類型安全,那么你可以嘗試顯式實現IFoo<Message1D, Message>
以及IFoo<Message1D, Message1D>
,如下所示:
public class Bar : IFoo<Message1D, Message1D>, IFoo<Message1D, Message>
{
public Message1D PassMessage(Message1D input)
{
// ...
}
Message1D IFoo<Message1D, Message>.PassMessage(Message input)
{
try
{
return PassMessage((Message1D) input);
}
catch (InvalidCastException)
{
// Message2D passed, handling exception
// ...
}
}
類似地為Baz
實現IFoo<Message2D, Message>
。
這將使您的代碼工作,但它很可能不是您的最佳決定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.