Я пытаюсь гибко использовать интерфейс IDictionary
в одном из моих методов, но из-за ограничений в отношении преобразования (см. C# type conversion: Explicit cast exists but throws a conversion error?) его использование очень ограничено для меня. Я хотел бы знать, есть ли способ обхода проблемы.Гибкое использование IDictionary (с интерфейсами)
Это моя конкретная проблема: У меня есть метод, который берет отображение, которое отображает каждую клавишу в IEnumerable из других ключей. Он также принимает один ключ в качестве входных данных. Что она делает это, чтобы найти закрытие набора/корпус данного ключа относительно отображения:
public static ISet<T> GetClosureSet(T element, IDictionary<T, IEnumerable<T>> elementToCollectionMap)
{
ISet<T> closure = new HashSet<T>();
closure.Add(element);
closure.UnionWith(elementToCollectionMap[element]);
int count = 0;
while (count != closure.Count)
{
count = closure.Count;
foreach (T elem in new HashSet<T>(closure))
closure.UnionWith(elementToCollectionMap[elem]);
}
return closure;
}
Пример такого отображения типа IDictionary<double, IEnumerable<double>>
:
1 -> [2, 3, 4]
2 -> [3, 7]
3 -> [3]
4 -> [] // empty enumerable, i.e. array of length 0
5 -> [6]
6 -> [6]
7 -> []
Если я положил ключ 1
и это сопоставление в моем методе, я получу [1, 2, 3, 4, 7]
: сначала 1
и его изображение [2, 3, 4]
собраны в комплект укупорки. Затем добавляются изображения 1
, 2
, 3
, 4
, поэтому мы также получаем 7
(в качестве элемента изображения 2
). На следующем этапе все изображения 1
, 2
, , 4
, 7
добавлены, но они уже находятся там. Таким образом, метод заканчивается и возвращается.
Как вы видите, это очень абстрактный метод, который не заботится о том, каковы ценности на самом деле. Для того, чтобы позвонить, UnionWith
, нужны только значения IEnumerable<T>
.
Но теперь я хочу иметь возможность использовать метод всякий раз, когда у меня есть сопоставление от ключей к каким-то коллекциям ключей!
У меня есть некоторые места в моем коде, где я определяю
IDictionary<MyType, HashSet<MyType>> foo = new Dictionary<MyType, HashSet<MyType>>();
и
IDictionary<MyType, List<MyType>> bar = new Dictionary<MyType, List<MyType>>();
и нужно их действительно IDictionary<MyType, HashSet<MyType>>
и IDictionary<MyType, List<MyType>>
, потому что мне нужна функциональность HashSet
и List
кроме того, что предоставлено IEnumerable
. Только позже я хочу получить закрытие. Но как сейчас, я не могу дать foo
и bar
в качестве входных данных для моего метода. Мне нужно создать из них новые словари, чтобы они соответствовали типу.
Любые идеи о том, как решить проблему (я не считаю «создание нового словаря для соответствия типу« решение »)?
Can 'Funct' have "no value" для некоторого ввода типа 'T', как' Словарь'? –
Kjara
@Kjara Если объект не имеет сопоставлений, то этот селектор должен возвращать пустую последовательность. Учитывая, что ваш словарь уже хранит пустую последовательность в качестве значения для этого ключа, вызывающему нужно написать «element => foo [element]». Конечно, если другой вызывающий абонент хранит свой граф в другой усадьбе целиком, они могут назвать это по-другому. – Servy
И может 'Func' be null? (Просто проверьте, нужно ли мне что-то менять в моем коде относительно недопустимого ввода.) –
Kjara