我有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
实例添加到列表中?
答案 0 :(得分:4)
如何将Bar和Baz实例添加到列表中?
您不能这样做,因为您试图将输入消息视为协变,但它是互变的。您可以将IFoo<Message1D, Message>
视为IFoo<Message, Message>
,但不能将IFoo<Message, Message1D>
视为IFoo<Message, Message>
。如果这是有效的,那么将允许某人将2D消息传递到只能处理1D消息的对象中。
答案 1 :(得分:0)
正如@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
// ...
}
}
为IFoo<Message2D, Message>
实现Baz
。
这将使您的代码正常工作,但这很可能不是您的最佳决定。