2015-07-14 2 views
0

У меня есть следующие строки, которые работают как предполагается.Как выбрать IEnumerable <T> вместо списка <T> от ICollection <T>?

Dictionary<Guid, List<T>> dictionary = source.ToDictionary(
    element => element.Id, 
    element => element.Ts.ToList()); 

Однако, я хотел бы первую линию использовать IEnumerable, который создает ошибку типа несоответствия.

Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(...); 

Использование ToArray вместо ToList мне не поможет (получение и ту же ошибку, плюс я научился не использовать массивы в C#, если на самом деле, на самом деле требуется) И, насколько я могу сказать , тип Ts является ICollection.

Можно ли преобразовать весь shabang так, как я желаю, не пройдя хардкор и используя литье?

ответ

2

Если вы хотите, чтобы избежать отливку, вы может использовать метод расширения AsEnumerable, который вернет правильный тип, но также скрыть исходный экземпляр/реализацию за анонимным перечислимым.

Я бы лично использовал только element => element.Ts as IEnumerable<T>, чтобы избежать вызова дополнительного метода только для удовлетворения ограниченного вывода дженериков.

2

Использование AsEnumerable(), который представляет собой удобный метод Linq, который просто возвращает исходный оттенок IEnumerable<T>:

Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
    element => element.Id, 
    element => element.Ts.AsEnumerable()); 

вы также можете попробовать литье:

Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
    element => element.Id, 
    element => (IEnumerable<T>)(element.Ts)); 
3

Это потому, что Dictionary<TKey, TValue> не является ковариантным. Таким образом, вы не можете выбрать Dictionary<string, List<T>> и направить его на Dictionary<string, IEnumerable<T>>, хотя List<T> реализует IEnumerable<T>. Зачем? Рассмотрим следующий код:

Dictionary<string, IEnumerable<int>> myDict = new Dictionary<string, List<int>>(); 
myDict.Add("key", new HashSet<int>()); 

С точки зрения компилятора, который был бы полностью нормально, потому что HashSet<T> реализует IEnumerable<T>. Но словарь ожидает, что значение будет List<T>!

Вы можете сделать бросок в ToDictionary методе:

Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary(
    element => element.Id, 
    element => (IEnumerable<T>)element.Ts.ToList()); 

или предоставить общие параметры типа для ToDictionary вызова:

Dictionary<Guid, IEnumerable<T>> dictionary = source.ToDictionary<Guid, IEnumerable<T>>(
    element => element.Id, 
    element => element.Ts.ToList()); 
+0

Х, я совершенно забыл о явной аннотации типа. Это победитель для меня. –

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