- •1. Работа с числами
- •2. Представление даты и времени
- •3. Работа со строками и текстом
- •4. Преобразование информации
- •5. Сравнение для выяснения равенства
- •6. Сравнение для выяснения порядка
- •7. Жизненный цикл объектов
- •7.1. Алгоритм сборки мусора
- •7.2. Финализаторы и интерфейс IDisposable
- •7.3. Слабые ссылки
- •8. Перечислители и итераторы
- •9. Стандартные интерфейсы коллекций
- •10. Массивы и класс System.Array
- •11. Типы для работы с коллекциями-списками
- •12. Типы для работы с коллекциями-множествами
- •13. Типы для работы с коллекциями-словарями
- •14. Типы для создания пользовательских коллекций
- •15. Технология LINQ to Objects
- •16. Работа с объектами файловой системы
- •17. Ввод и вывод информации
- •17.1. Потоки данных и декораторы потоков
- •17.2. Адаптеры потоков
- •18. Основы XML и JSON
- •19. Технология LINQ to XML
- •20. Дополнительные возможности обработки XML
- •21. Сериализация времени выполнения
- •22. Сериализация контрактов данных
- •23. Состав и взаимодействие сборок
- •24. Метаданные и получение информации о типах
- •25. Позднее связывание и кодогенерация
- •26. Атрибуты
- •27. Динамическое связывание
- •28. Файлы конфигурации
- •29. Диагностика и мониторинг
- •30. Процессы и домены
- •31. Основы многопоточного программирования
- •32. Синхронизация потоков
- •32.1. Критические секции
- •32.2. Синхронизация на основе подачи сигналов
- •32.3. Неблокирующие средства синхронизации
- •32.4. Разделение данных между потоками
- •33. Выполнение асинхронных операций при помощи задач
- •33.1. Базовые сведения о задачах
- •33.2. Обработка исключений и отмена выполнения задач
- •33.3. Продолжения
- •33.4. Асинхронные функции в C#
- •34. Платформа параллельных вычислений
- •34.1. Параллелизм при императивной обработке данных
- •34.2. Параллелизм при декларативной обработке данных
- •34.3. Коллекции, поддерживающие параллелизм
- •35. Асинхронный вызов методов
- •Литература
public class LastFirstComparer : EqualityComparer<Customer>
{
public override bool Equals(Customer x, Customer y)
{
return x.LastName == y.LastName && x.FirstName == y.FirstName;
}
public override int GetHashCode(Customer obj)
{
return (obj.LastName + ";" + obj.FirstName).GetHashCode();
}
}
Статическое свойство EqualityComparer<T>.Default возвращает экземпляр EqualityComparer<T> для типа T. Этот экземпляр использует метод Equals(T) либо метод Equals(object) в зависимости от того, реализует ли тип T интерфейс
IEquatable<T>.
Ранее указывалось, что по умолчанию структуры реализуют равенство по значению: две структуры равны, если равны значения всех их соответствующих
элементов. Интерфейс System.Collections.IStructuralEquatable позволяет пе-
ренести данную семантику на другие типы. На платформе .NET этот интерфейс явно реализуют любые массивы и кортежи (классы вида System.Tuple<>).
public interface IStructuralEquatable
{
bool Equals(object other, IEqualityComparer comparer); int GetHashCode(IEqualityComparer comparer);
}
Передаваемый в метод Equals() объект comparer применяется к каждому индивидуальному элементу в составном объекте. Следующий пример демонстрирует использование IStructuralEquatable.
string[] low = "the quick brown fox".Split(); string[] high = "THE QUICK BROWN FOX".Split(); IStructuralEquatable se = low;
// переменная f равна true
bool f = se.Equals(high, StringComparer.InvariantCultureIgnoreCase);
6. Сравнение для выяснения порядка
Стандартным способом сравнения для выяснения порядка является реали-
зация типом интерфейсов IComparable и IComparable<T>:
public interface IComparable
{
int CompareTo(object other);
}
19
public interface IComparable<in T>
{
int CompareTo(T other);
}
Оба интерфейса предоставляют одинаковый функционал. Универсальный интерфейс IComparable<T> избавляет от необходимости упаковки при работе с типами значений. Метод x.CompareTo(y) должен возвращать любое положительное число, если x «больше» y, отрицательное число, если x «меньше» y, и ноль, если x и y равны.
Базовые типы реализуют обе версии интерфейса IComparable. В типе string метод CompareTo() выполняет чувствительное к регистру сравнение строк с учётом региональных стандартов. В некоторых базовых типах дополнительно определён статический метод сравнения Compare(). Например, string имеет перегруженные версии Compare(), которые принимают или элемент перечисления StringComparison, или булев флаг (игнорирование регистра) и объект
CultureInfo:
string s1 = "Strasse", s2 = "Straße"; // порядковое сравнение, i = -108
int i = string.Compare(s1, s2, StringComparison.Ordinal); // j = 0, так как в немецком языке такие слова равны
int j = string.Compare(s1, s2, false, new CultureInfo("de-DE"));
Кроме реализации IComparable и IComparable<T> тип может дополнительно перегружать операции < и >. Перегрузка операций сравнения обычно выполняется, если результат операции не зависит от контекста выполнения1.
bool isAfterDoomsday = DateTime.Now > new DateTime(2012, 12, 21);
Как и в случае проверки на равенство, сравнение для выяснения порядка можно выполнить при помощи подключаемых интерфейсов. Для порядкового сравнения предназначены интерфейсы IComparer<T> и IComparer (пространства
имён System.Collections.Generic и System.Collections).
public interface IComparer
{
int Compare(object x, object y);
}
public interface IComparer<in T>
{
int Compare(T x, T y);
}
1 Тип string не перегружает операции сравнения, так как результат может измениться в зависимости от текущих региональных стандартов.
20