Как перебрать (итерировать) все элементы словаря Dictionary в C#?
Основной способ: перебор через KeyValuePair
В C# словарь Dictionary<TKey, TValue> реализует интерфейс IEnumerable<KeyValuePair<TKey, TValue>>. Это значит, что при использовании foreach каждый элемент цикла будет иметь тип KeyValuePair<TKey, TValue>, у которого есть свойства Key и Value. Ваш код был почти правильным, но нужно явно указать тип переменной или использовать var.
Вот исправленный пример:
Dictionary<string, int> students = new Dictionary<string, int>
{
{ "Анна", 85 },
{ "Борис", 92 },
{ "Виктор", 78 }
};
// Вариант 1: явное указание типа
foreach (KeyValuePair<string, int> entry in students)
{
Console.WriteLine($"{entry.Key}: {entry.Value}");
}
// Вариант 2: с var (компилятор сам подставит тип)
foreach (var entry in students)
{
Console.WriteLine($"{entry.Key}: {entry.Value}");
}
Альтернативные способы перебора
- Перебор только ключей — используйте свойство
Keys:
foreach (string name in students.Keys)
{
Console.WriteLine($"{name}: {students[name]}");
}
- Перебор только значений — свойство
Values:
foreach (int grade in students.Values)
{
Console.WriteLine($"Оценка: {grade}");
}
- Метод ForEach (только для списков) — для словарей напрямую не работает, но можно преобразовать в список:
students.ToList().ForEach(entry => Console.WriteLine($"{entry.Key}: {entry.Value}"));
Важные замечания
1. Не изменяйте словарь во время перебора — добавление или удаление элементов внутри цикла foreach вызовет исключение InvalidOperationException. Если нужно модифицировать словарь, соберите ключи в отдельный список:
List<string> keysToRemove = new List<string>();
foreach (var entry in students)
{
if (entry.Value < 80)
keysToRemove.Add(entry.Key);
}
foreach (string key in keysToRemove)
students.Remove(key);
2. Порядок элементов — в обычном Dictionary порядок не гарантирован. Если важен порядок добавления, используйте OrderedDictionary (из System.Collections.Specialized) или SortedDictionary.
3. Производительность — перебор через foreach по словарю очень быстрый (O(n)). Для больших словарей избегайте обращения по ключу внутри цикла (например, students[key]), если ключ уже есть в entry.Key — это лишний поиск.
Таким образом, самый простой и читаемый способ — использовать foreach (var entry in dictionary) и обращаться к entry.Key и entry.Value. Этот подход работает во всех версиях C#, начиная с .NET Framework 2.0.
Использование LINQ для гибкого перебора
Если вам нужно не просто вывести все элементы, а выполнить фильтрацию, проекцию или сортировку, удобно использовать LINQ. Методы расширения работают со словарём как с коллекцией пар «ключ-значение».
Примеры:
using System.Linq;
// Вывести только студентов с оценкой выше 80
var highGrades = students.Where(kvp => kvp.Value > 80);
foreach (var entry in highGrades)
Console.WriteLine($"{entry.Key}: {entry.Value}");
// Получить отсортированный список по имени
var sorted = students.OrderBy(kvp => kvp.Key);
foreach (var entry in sorted)
Console.WriteLine($"{entry.Key}: {entry.Value}");
// Преобразовать в список строк
List<string> result = students
.Select(kvp => $"{kvp.Key} - {kvp.Value}")
.ToList();
LINQ-запросы выполняются лениво (отложенное выполнение), поэтому если вы планируете перебирать результат несколько раз, лучше материализовать его через .ToList() или .ToArray(). Это особенно важно, если исходный словарь может измениться между проходами.
Также обратите внимание на метод TryGetValue — он безопаснее, чем обращение через индексатор, если ключа может не быть:
if (students.TryGetValue("Анна", out int grade))
Console.WriteLine($"Анна: {grade}");
else
Console.WriteLine("Студент не найден");
LINQ даёт большую гибкость, но для простого перебора лучше использовать классический foreach — он читается легче и не требует дополнительных using-директив.
Ответов пока нет.
Войдите чтобы оставить ответ