Интерфейс C # как проблема преобразования типов параметров - PullRequest
1 голос
/ 14 июня 2011

У меня есть этот метод ...

public static IList<IOutgoingMessage> CompressMessages(IList<IOutgoingMessageWithUserAndPtMedInfo> msgs)
    {
        StoreOriginalMessages(msgs);
        ...
    }

, который вызывает этот метод ...

 private static void StoreOriginalMessages(IList<IOutgoingMessage> msgs) {...}

и IOutgoingMessageWithUserAndPtMedInfo определяется следующим образом ...

public interface IOutgoingMessageWithUserAndPtMedInfo: IOutgoingMessage
{
    IPatientMedication PatientMedication { get; set; }
    IUserContainer User{ get; set; }
}

Я получаю эту ошибку, когда пытаюсь вызвать StoreOriginalMessages из моего CompressMessages метода:

не удается преобразовать из 'System.Collections.Generic.IList <MyMediHealth.DataAccess.Containers.IOutgoingMessageWithUserAndPtMedInfo>' в'System.Collections.Generic.IList <MyMediHealth.DataAccess.Containers.IOutgoingMessage>'

Не понимаю, почему.Я ожидаю, что он примет это, потому что IOutgoingMessageWithUserAndPtMedInfo наследуется от IOutgoingMessage.

Что я делаю не так?

Ответы [ 2 ]

5 голосов
/ 14 июня 2011

Ссылка: Ковариация и контравариантность в родовых типах

Предполагается, что следующие 2 интерфейса и 2 класса:

interface IBase {}
interface IDerived : IBase {}

class Base {}
class Derived : Base {}

Если вы сделаете это, вы получите ту же ошибку приведения:

IList<IDerived> lid = null;
IList<IBase> lib = lid; //cannot cast IList<IDerived> to IList<IBase>

IList<Derived> ld = null;
IList<Base> lb = ld; //cannot cast IList<Derived> to IList<Base>

Однако следующее скомпилируется просто отлично, потому что IEnumerable<T> объявлен для ковариации, где IList<T> - нет. IEnumerable<T> на самом деле IEnumerable<out T>, что означает, что параметр типа предназначен только для возвращаемых значений и может допускать ковариацию.

IEnumerable<IDerived> lid = null;
IEnumerable<IBase> lib = lid;

IEnumerable<Derived> ld = null;
IEnumerable<Base> lb = ld;
3 голосов
/ 14 июня 2011

Из названий ваших методов я заключаю, что StoreOriginalMessages не вставляет новые элементы в список?

Вы можете заменить его на

private static void StoreOriginalMessages(IEnumerable<IOutgoingMessage> msgs)

И он должен работать гладко (если выиметь C # 4.0 - до того как не было поддержки ковариации, к сожалению).

Если вы работаете с C # 3.5, вам также необходимо изменить сайт вызова:

StoreOriginalMessages(msgs.Cast<IOutgoingMessage>());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...