Biorąc pod uwagę następujący przykład LINQPad:Dlaczego IEnumerable nie potrzebuje rzutu, ale robi to lista?
void Main()
{
List<DbItem> dbItems = new List<DbItem>
{
new DbItem{Id = 4, SomeValue = "Value For 4", OtherValue = 1},
new DbItem{Id = 19, SomeValue = "Value For 19", OtherValue = 2}
};
ListMethod(dbItems.Cast<IDbItem>().ToList()); <-+
EnumerableMethod(dbItems); <-+
} |
|
// These are the methods are I asking about -------+
public void ListMethod(List<IDbItem> dbItems)
{
Console.WriteLine(dbItems);
}
public void EnumerableMethod(IEnumerable<IDbItem> dbItems)
{
Console.WriteLine(dbItems);
}
public class DbItem : IDbItem
{
public int Id {get; set;}
public string SomeValue {get; set;}
public int OtherValue {get; set;}
}
public interface IDbItem
{
int Id {get; set;}
string SomeValue {get; set;}
}
Dlaczego EnumerableMethod
podjęcia listę bezpośrednio podczas ListMethod
musi najpierw obsady?
Dostaję, że obsada dzieje się od DbItem do IDbItem, ale co różni się od IEnumerable, która pozwala mu obsadzić bez wyraźnego żądania?
Wyobrażam sobie, że odpowiedź zawiera słowo Kowariancja, ale nie wiem wystarczająco dużo o tym, aby samemu to zrozumieć.
dostaję, że pies jest naprawdę lista psów i nie Zwierząt. Ale dlaczego to działa dla IEnumerable? – Vaccano
'IEnumerable' nie ma metody' Add', więc nie ma obaw przed dodaniem 'Cat' do' dogs'. Kowariancja jest czymś, co musi być wyraźnie określone, a ci, którzy stworzyli "List" zdecydowali, że nie powinna ona być kowariantna z powyższego powodu. Faceci, którzy stworzyli "IEnountable" zdecydowali, że powinno to być kowariantne. – ShadowCat7