2014-11-20 2 views
0

Я пытаюсь использовать List в IList, но не могу его отличить. Компилятор позволяет мне брось только в IEnumerable:Невозможно выполнить листинг Список в IList

//Not allowed, why? 
public override IList<ILineEntity> Lines 
{ 
    get { return _PharamaLines ?? (_PharamaLines = new List<PharamaLine>()); } 
} 

//Allowed 
public override IEnumerable<ILineEntity> Lines 
{ 
    get { return _PharamaLines ?? (_PharamaLines = new List<PharamaLine>()); } 
} 

PharamaLine имеет тип ILineEntity.

Error: Cannot implicitly convert type ' System.Collections.Generic.List<FW.PharamaLine> ' to ' System.Collections.Generic.IList<Foundation.Interfaces.ILineEntity> '. An explicit conversion exists (are you missing a cast?)

+0

Что такое '' PharamaLine'? –

+1

@PatrickHofman имеет значение? –

+0

@PatrickHofman 'ILineEntity' –

ответ

2

Причина заключается в том:

IList<T>является инвариантом, а IEnumerable<out T> является ковариантны (out ключевого слова).

Если определить List<PharamaLine>, вы в основном утверждаете, что вы можете только добавить PharmaLine объектов в список, но вы можете добавить различныеILineEntity объектов в IList<ILineEntity>, и что бы разорвать контракт.

Предположим, у вас есть класс OtherLine : ILineEntity. Представьте себе, этот код был действителен:

var list = new List<PharmaLine>(); 
var list2 = (IList<ILineEntity>)list; // Invalid! 
list2.Add(new OtherLine()); // This should work if the cast were valid 

Это работает для перечислимого, так как последовательность PharmaLine является всегда действительная последовательность ILineEntity (ковариации).

Обратите внимание, что вы также можете использовать IReadOnlyList<out T>, который также является ковариантным, но не имеет методов, которые позволяют вам изменять список.

+0

Тогда что мне делать, если я хочу добавить 'PharamaLine' в' Lines'? Я имею в виду, какой контракт? –

+0

Вы можете использовать 'List ' **, если ** это то, что должен означать ваш код. –

+0

Или вы можете использовать 'IReadOnlyList ' –

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