2016-07-22 3 views
2

У меня есть следующий интерфейс:Почему общая котировка прерывания генерируется, даже если она ограничена?

public interface ICommand<TMessage> 
    where TMessage : MessageBase 
{ 
    TMessage Message { get; set; } 
} 

Я хотел бы быть в состоянии бросить реализации IMessage но чтобы это было возможно, параметр типа должен быть ковариантны, например, так:

public interface ICommand<out TMessage> 
    where TMessage : MessageBase 
{ 
    TMessage Message { get; set; } 
} 

Но тогда компилятор жалуется: параметр типа «TMessage» должен быть инвариантным для ICommand.Message. «TMessage» является ковариантным. Если я удаляю сеттер, все работает отлично.

Однако, я не понимаю, почему это сеттер представляет проблему теоретически, потому что я уточнил, что свойство Message может сохранить только ссылку на экземпляры более производных типов MessageBase ...

ответ

2

Ничего, после предоставления это немного больше мысли, на самом деле довольно легко увидеть.

Пусть I экземпляр DerivedCommand<T> (который реализует ICommand<T>)

var derivedCommand = new DerivedCommand<DerivedMessage>(); 

, а затем бросить его ICommand<MessageBase>

var command = (ICommand<MessageBase>) derivedCommand; 

Это будет означать, что теперь я могу назначить любой экземпляр типа в сообщение имущество. Но, поскольку свойство действительно имеет тип DerivedMessage, который является более производным, чем , он не работает во всех случаях (где AnotherMessage происходит от , но не от DerivedMessage). Поэтому сеттеры не могут быть ковариантными, даже если тип ограничен.

+3

Не говорите свой ответ так, как будто вы еще не знали об этом, прежде чем отправили вопрос. Вы отправили их почти в одно и то же время, вам не нужно притворяться, будто вы «немного подумали» – musefan

+2

... хотя я удивлен такими быстрыми позициями ... несколькими учетными записями или просто друзьями? – musefan

+0

Извините, но SO просто дает возможность задать вопрос и ответить на ваш вопрос одновременно. Поскольку я понял, почему сразу после моего вопроса я сразу добавил ответ. Формулирование этого вопроса заняло более 5 минут. И нет нескольких учетных записей. В равной степени удивлен быстрым повышением. – mstaessen

Смежные вопросы