C# 为什么泛型setter即使在受约束的情况下也会破坏类型协方差?

C# 为什么泛型setter即使在受约束的情况下也会破坏类型协方差?,c#,C#,我有以下界面: public interface ICommand<TMessage> where TMessage : MessageBase { TMessage Message { get; set; } } 公共接口ICommand 其中TMessage:MessageBase { TMessage消息{get;set;} } 我希望能够将实现强制转换为IMessage,但要做到这一点,类型参数必须是协变的,如下所示: public interface

我有以下界面:

public interface ICommand<TMessage> 
    where TMessage : MessageBase 
{
    TMessage Message { get; set; }
}
公共接口ICommand
其中TMessage:MessageBase
{
TMessage消息{get;set;}
}
我希望能够将实现强制转换为IMessage,但要做到这一点,类型参数必须是协变的,如下所示:

public interface ICommand<out TMessage> 
    where TMessage : MessageBase 
{
    TMessage Message { get; set; }
}
公共接口ICommand
其中TMessage:MessageBase
{
TMessage消息{get;set;}
}
但是,编译器会抱怨:类型参数“TMessage”必须在ICommand.Message上始终有效“TMessage”是协变的。 如果我移除setter,一切正常


但是,我不理解为什么这个setter在理论上会带来问题,因为我已经指定Message属性只能保留对更多派生类型的MessageBase的引用…

没关系,在仔细考虑之后,实际上很容易看到它

假设我实例化了一个
DerivedCommand
(它实现了
ICommand

var-derivedCommand=new-derivedCommand();
然后将其强制转换为
ICommand

var命令=(ICommand)派生命令;

这意味着我现在可以将
MessageBase
类型的任何实例分配给Message属性。但是,由于属性的类型实际上是
DerivedMessage
,它比
MessageBase
派生得多,因此它并不适用于所有情况(其中
AnotherMessage
确实派生自
MessageBase
,但不是派生自
DerivedMessage
)。因此,即使在类型受限的情况下,setter也不能是协变的。

在发布问题之前,不要把你的答案当作你还不知道的话。你几乎是在同一时间发布的,你不需要假装你“多想了一想”…尽管我对这么快的投票感到惊讶。。。多个帐户,或者只是朋友?抱歉,但是这样就可以同时询问和回答您的问题。因为我刚做完我的问题就明白了为什么,所以我立即补充了答案。提出这个问题花了5分钟多。没有多个帐户。同样令人惊讶的是,这篇文章的答案和问题都很快就出来了。如果问题显示出来并且回答得很好,我会忽略措辞。@Sinatr:是的,我知道,我只是在说一些想法
var derivedCommand = new DerivedCommand<DerivedMessage>();
var command = (ICommand<MessageBase>) derivedCommand;