Как показывает ошибка, вы пытаетесь сделать что-то, чего не существует.
Один из переопределенных конструкторов Dictionary принимает
public Dictionary(IDictionary<TKey, TValue> dictionary);
public Dictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer);
И ни один из указанных вами параметров не является правильным.
Первый ввод, который вы дали, это Task [], а второй - CancellationToken []
.
Вы должны создать реализацию IDictionary, которая обычно представляет собой словарь, а затем передать его ему.
var example1Original = new Dictionary<Task, CancellationToken>();
example1Original.Add(new Task(DoWork), new CancellationToken());
example1Original.Add(new Task(DoWork), new CancellationToken());
// and more (This procedure can be shorten using a loop)
var example1Result = new Dictionary<Task, CancellationToken>(example1Original);
Как видите, мы успешно передали нашу переменную в конструктор Dictionary, это возможно потому, что Dictionary реализует IDictionary, как мы можем видеть здесь
">
Но последняя строка фактически избыточна, потому что да, мы можем ее пропустить, но нам это не нужно. Потому что наш заполненный пример exampleOriginal уже является словарем, к которому мы стремимся.
Таким образом, возникает вопрос, почему конструктор Dictionary имеет это в первую очередь. Это приводит нас к нашему первоначальному утверждению, что IDictionary может иметь несколько реализаций, которые можно передавать.
Вот несколько реализаций IDictionary
implementations">
(Изображение взято с mscorlib.dll с использованием ILSpy)
Итак, ваш вопрос на самом деле, как я могу заполнить свой словарь новыми экземплярами жетонов задач и отмены.
Это можно сделать с помощью:
- Предыдущий код выше. (И укоротить еще на петлю)
- Или используя более короткие языковые возможности.
Возможности, которые мы собираемся использовать
- System.Linq.Enumerable.Range - генерирует последовательность целых чисел в указанном диапазоне.
- System.Linq.Enumerable.Select - Проецирует каждый элемент последовательности в новую форму.
- Сила интерфейсов - для того, чтобы мы могли использовать метод расширения ToDictionary.
- System.Linq.Enumrable.ToDictionary () - Метод расширения, который принимает IEnumerable и генерирует словарь
Enumerable.ToDictionary - поскольку сам IDictionary реализует IEnumerable, мы можем затем использовать следующий метод расширения ToDictionary
Метод расширения из System.Linq Пространство имен
public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector);
Если мы будем использовать эти возможности, мы можем создать следующее для создания нашего словаря.
var kvpOfTaskCancellation = Enumerable.Range(0, 9) // Generates Enumerable integers sequence.
.Select(i => new KeyValuePair<Task, CancellationToken>(new Task(DoWork), new CancellationToken())) // Iterating and projecting every elements inside the previous generated sequence.
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // Mapping each iteration from the previous line KeyValuePair objects to the Dictionary Key and Value.
Что также можно сократить до следующего
var kvpOfTaskCancellation2 = Enumerable.Range(0, 9)
.ToDictionary(kvp => new Task(DoWork), kvp => new CancellationToken());
Это все работает, если вам нужен новый маркер Задачи и Отмена.
Но Если у вас уже есть заполненная коллекция Tasks и CancellationTokens, и вы хотите сгенерировать из них словарь, вы можете сделать следующее:
var tasks = new Task[3];
// I'm assuming the tasks already been populated
tasks.ToDictionary(kvp => kvp, kvp => new CancellationToken());
Но если у вас также есть массив CancellationToken, то вы можете использовать следующее:
var tasks = new Task[3];
var cancellationsTokens = new CancellationToken[9];
// I'm assuming tasks and cancellationToken array already been filled.
Enumerable.Range(0, tasks.Length)
.Select(i => new KeyValuePair<Task, CancellationToken>(tasks[i], cancellationsTokens[i]))
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);