带有变量类型参数的C#强制转换类.代码片段对此进行了解释
本文关键字:片段 代码 解释 转换 类型参数 变量 | 更新日期: 2023-09-27 18:02:23
为什么这不起作用,我如何使它起作用?在这种情况下,M直接实现了IMessage,我得到了一个InvalidCastException。
public void Subscribe<M>(IMessageListener<M> listener) where M : IMessage
{
IMessageListener<IMessage> l = (IMessageListener<IMessage>)listener;
}
当M
实现IMessage
时,将IMessageListener<M>
强制转换为IMessageListener<IMessage>
不应该工作吗?
很抱歉标题不好,不知道如何描述。
//编辑IMessageListener类如下所示:
public interface IMessageListener<M> where M : IMessage
{
void ProcessMessage(M message);
}
简短回答:不,它不应该工作。
public class MessageA : IMessage
{
public int SpecificAField;
}
public class MessageB : IMessage {}
public class MessageAListener : IMessageListener<MessageA>
{
public void ProcessMessage(MessageA message)
{
messageA.SpecificAField = 3;
}
}
如果编译器让Subscribe<MessageA>
?将MessageAListener
强制转换为IMessageListener<IMessage>
,然后可以传递给它一个MessageB
。
然后MessageAListener
会尝试在MessageB
上设置SpecificAField
,但它没有。
这不起作用,因为IMessageListener<T>
是T
上的反变量——它仅将T
引用为输入。因此,您可以将IMessageListener<IMessage>
强制转换为IMessageListener<MessageA>
,因为它很乐意接受MessageA
作为输入来代替IMessage
。
要执行的强制转换要求IMessageListener<T>
是T
上的协变-它必须仅将T
引用为输出。然后,您可以将IMessageListener<MessageA>
强制转换为IMessageListener<IMessage>
,因为真正的返回类型MessageA
可以转换为预期的返回类型IMessage
。