带有变量类型参数的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);
}

带有变量类型参数的C#强制转换类.代码片段对此进行了解释

简短回答:不,它不应该工作。

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