Загрузка данных
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
// List<T> — динамический массив, ТИПИЗИРОВАННЫЙ.
// Компилятор не даст положить сюда строку, если T = int.
List<int> numbers = new List<int> { 5, 3, 8, 1, 9, 3 };
numbers.Add(7); // добавить в конец
numbers.Insert(0, 100); // вставить по индексу
numbers.Remove(3); // удалить первое вхождение
numbers.RemoveAt(0); // удалить по индексу
Console.WriteLine("Числа: " + string.Join(", ", numbers));
Console.WriteLine($"Count = {numbers.Count}");
numbers.Sort(); // сортировка по возрастанию
Console.WriteLine("Отсортировано: " + string.Join(", ", numbers));
// LINQ поверх List<T>
Console.WriteLine($"Сумма: {numbers.Sum()}");
Console.WriteLine($"Среднее: {numbers.Average():F2}");
Console.WriteLine($"Максимум: {numbers.Max()}");
// Dictionary<TKey, TValue> — хеш-таблица «ключ → значение».
// Ключи ДОЛЖНЫ быть уникальны, иначе будет исключение.
var phoneBook = new Dictionary<string, string>
{
["Иван"] = "+7-900-111-11-11",
["Мария"] = "+7-900-222-22-22",
["Пётр"] = "+7-900-333-33-33"
};
// Безопасное добавление через TryAdd — не бросает исключение.
phoneBook.TryAdd("Иван", "+7-000-000-00-00"); // проигнорируется
// Перебор словаря: KeyValuePair<K,V>.
foreach (var pair in phoneBook)
{
Console.WriteLine($"{pair.Key}: {pair.Value}");
}
// Безопасное извлечение через TryGetValue.
if (phoneBook.TryGetValue("Мария", out string phone))
Console.WriteLine($"Телефон Марии: {phone}");
Console.WriteLine($"Есть ли Пётр? {phoneBook.ContainsKey("Пётр")}");
// Queue<T> — очередь, работает по принципу FIFO (первым пришёл — первым вышел).
var queue = new Queue<string>();
queue.Enqueue("Задача 1");
queue.Enqueue("Задача 2");
queue.Enqueue("Задача 3");
Console.WriteLine($"В очереди: {queue.Count}");
while (queue.Count > 0)
{
// Dequeue достаёт и удаляет элемент из начала очереди.
Console.WriteLine("Обрабатываю: " + queue.Dequeue());
}
// Stack<T> — стек, работает по принципу LIFO (последним пришёл — первым вышел).
var stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
stack.Push(3);
while (stack.Count > 0)
{
// Pop достаёт элемент с вершины стека.
Console.WriteLine("Со стека: " + stack.Pop());
}
// HashSet<T> хранит ТОЛЬКО уникальные значения.
// Внутри — хеш-таблица, поэтому Contains работает за O(1).
var setA = new HashSet<int> { 1, 2, 3, 4, 5 };
var setB = new HashSet<int> { 4, 5, 6, 7 };
setA.Add(3); // проигнорируется, 3 уже есть
Console.WriteLine("Объединение: " + string.Join(", ", setA.Union(setB)));
Console.WriteLine("Пересечение: " + string.Join(", ", setA.Intersect(setB)));
Console.WriteLine("Разность A\\B: " + string.Join(", ", setA.Except(setB)));
// Box<T>
var intBox = new Box<int>(42);
var strBox = new Box<string>("Привет");
Console.WriteLine(intBox); // Box<Int32>(42)
Console.WriteLine(strBox); // Box<String>(Привет)
intBox.Set(100);
Console.WriteLine(intBox.Get()); // 100
// strBox.Set(5); // × Ошибка компиляции: ожидается string, получено int
// Pair<TKey, TValue>
var pair1 = new Pair<string, int>("Возраст", 25);
var pair2 = new Pair<int, string>(1, "Один");
Console.WriteLine(pair1); // [Возраст => 25]
Console.WriteLine(pair2); // [1 => Один]
// Обобщённый метод
Console.WriteLine(Max(3, 7)); // 7
Console.WriteLine(Max("abc", "xyz")); // xyz
Console.WriteLine(Max(3.14, 2.71)); // 3.14
// MyList<T>
var myList = new MyList<string>();
myList.Add("раз");
myList.Add("два");
myList.Add("три");
for (int i = 0; i < myList.Count; i++)
Console.WriteLine(myList[i]);
// Старый необобщённый ArrayList хранит object — это плохо:
var badList = new System.Collections.ArrayList();
badList.Add(1);
badList.Add("строка"); // компилятор не против!
badList.Add(3.14);
// int x = (int)badList[1]; // × InvalidCastException в рантайме!
// List<T> такую ошибку поймает ещё при компиляции.
}
// Обобщённые методы — как обобщённые классы, но для одного метода.
// where T : IComparable<T> — ограничение: T должен уметь сравниваться.
static T Max<T>(T a, T b) where T : IComparable<T>
{
return a.CompareTo(b) > 0 ? a : b;
}
}
// Параметр T — это "заглушка" типа, которая подставится
// при создании объекта: new Box<int>(...), new Box<string>(...) и т.д.
class Box<T>
{
private T _value; // тип поля определяется при создании
public Box(T value)
{
_value = value;
}
public T Get()
{
return _value;
}
public void Set(T value)
{
_value = value;
}
// Переопределение ToString использует значение.
public override string ToString() => $"Box<{typeof(T).Name}>({_value})";
}
// Параметров типа может быть несколько: <TKey, TValue>.
class Pair<TKey, TValue>
{
public TKey Key { get; }
public TValue Value { get; }
public Pair(TKey key, TValue value)
{
Key = key;
Value = value;
}
public override string ToString() => $"[{Key} => {Value}]";
}
// Простая реализация динамического массива — для понимания, как устроен List<T>.
class MyList<T>
{
private T[] _items = new T[4]; // стартовая ёмкость
public int Count { get; private set; }
public void Add(T item)
{
if (Count == _items.Length)
Array.Resize(ref _items, _items.Length * 2); // расширяем вдвое
_items[Count++] = item;
}
// Индексатор — позволяет писать list[0], list[1] и т.д.
public T this[int index]
{
get
{
if (index < 0 || index >= Count)
throw new IndexOutOfRangeException();
return _items[index];
}
}
}