Как выбрать IEnumerable<T> вместо List<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.
Можно ли преобразовать весь шабанг так, как я хочу, не используя хардкор и не используя кастинг?
3 ответа
Если вы хотите избежать кастинга, вы можете использовать AsEnumerable
метод расширения, который возвращает правильный тип, но также скрывает исходный экземпляр / реализацию за анонимным перечислимым.
Я бы лично просто использовал element => element.Ts as IEnumerable<T>
однако, чтобы избежать вызова дополнительного метода только для удовлетворения ограниченного вывода обобщений.
Это потому что 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());
Использование 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));