Я узнал, что HashSet
реализует интерфейс IEnumerable
. Таким образом, можно неявно отбрасывать HashSet
объект в IEnumerable
:Преобразование типа C#: Явное литье существует, но выдает ошибку преобразования?
HashSet<T> foo = new HashSet<T>();
IEnumerable<T> foo2 = foo; // Implicit cast, everything fine.
Это работает для вложенных универсальных типов, тоже:
HashSet<HashSet<T>> dong = new HashSet<HashSet<T>>();
IEnumerable<IEnumerable<T>> dong2 = dong; // Implicit cast, everything fine.
По крайней мере, это то, что я думал. Но если я сделаю Dictionary
, я столкнулся с проблемой:
IDictionary<T, HashSet<T>> bar = new Dictionary<T, HashSet<T>>();
IDictionary<T, IEnumerable<T>> bar2 = bar; // compile error
Последняя строка дает мне следующую ошибку компиляции (Visual Studio 2015):
Не может неявно преобразовать тип
System.Collections.Generic.IDictionary<T, System.Collections.Generic.HashSet<T>>
доSystem.Collections.Generic.IDictionary<T, System.Collections.Generic.IEnumerable<T>>
.Явное преобразование существует (вы пропали без вести броска?)
Но если я бросание написав
IDictionary<T, IEnumerable<T>> bar2 = (IDictionary<T, IEnumerable<T>>) bar;
тогда я получаю недопустимое исключение во время выполнения броска.
Два вопроса:
- Как решить эту проблему? Является единственным способом перебора ключей и создания нового словаря по-разному?
- Зачем мне эта проблема в первую очередь, хотя
HashSet
действительно реализует интерфейсIEnumerable
?
'' IEnumerable является [ковариантный] (https://msdn.microsoft.com/en-gb/library/mt654060.aspx). 'IDictionary ' нет. Это * внешние * типы, где это важно –