- •А.А. Волосевич
- •2. Базовые технологии платформы .Net 5
- •2. Базовые технологии платформы .Net 4
- •2. Базовые технологии платформы .Net
- •2.1. Работа с Числами
- •2.2. Дата и время
- •2.3. Работа со строками и текстом
- •2.4. Преобразование информации
- •2.5. Отношения равенства и порядка
- •Сравнение для выяснения равенства
- •Сравнение для выяснения порядка
- •2.6. Жизненный цикл объектов
- •Алгоритм «сборки мусора»
- •Финализаторы и интерфейс iDisposable
- •2.7. Перечислители и итераторы
- •2.8. Интерфейсы стандартных коллекций
- •2.9. Массивы и класс system.Array
- •2.10. Типы для работы с коллекциями-списками
- •2.11. Типы для работы с коллекциями-множествами
- •2.12. Типы для работы с коллекциями-словарями
- •2.13. Типы для создания пользовательских коллекций
- •2.14. Технология linq to objects
- •1. Оператор условия Where().
- •2. Операторы проекций.
- •3. Операторы упорядочивания.
- •4. Оператор группировки GroupBy().
- •5. Операторы соединения.
- •6. Операторы работы с множествами.
- •7. Операторы агрегирования.
- •8. Операторы генерирования.
- •9. Операторы кванторов и сравнения.
- •10. Операторы разбиения.
- •11. Операторы элемента.
- •12. Операторы преобразования.
- •2.15. Работа с объектами файЛовой системы
- •2.16. Ввод и вывод информации
- •Потоки данных и декораторы потоков
- •2. Классы для работы с потоками, связанными с хранилищами.
- •3. Декораторы потоков.
- •4. Адаптеры потоков.
- •Адаптеры потоков
- •2.17. Основы xml
- •2.18. Технология linq to xml
- •Создание, сохранение, загрузка xml
- •Запросы, модификация и трансформация xml
- •Пространства имен xml
- •2.19. ДОполнительные возможности обработки xml
- •2.20. Сериализация
- •Сериализация времени выполнения
- •Сериализация контрактов данных
- •2.21. Состав и взаимодействие сборок
- •2.22. Метаданные и получение информации о типах
- •2.23. Позднее связывание и кодогенерация
- •2.24. Динамические типы
- •2.25. Атрибуты
- •2.26. Файлы конфигуРации
- •2.27. Основы мНогопоточноГо программирования
- •2.28. Синхронизация потоков
- •2.29. Библиотека параллельных расширений
- •Параллелизм на уровне задач
- •Параллелизм при императивной обработке данных
- •Параллелизм при декларативной обработке данных
- •Обработка исключений и отмена выполнения задач
- •Коллекции, поддерживающие параллелизм
- •2.30. Асинхронный вызов методов
- •2.31. Процессы и домены
- •2.32. Безопасность
- •Разрешения на доступ
- •Изолированные хранилища
- •Криптография
- •2.33. Диагностика
2.4. Преобразование информации
Платформа .NET и языки программирования, построенные на её основе, предлагают богатый набор средств для решения задачи преобразования информации в данные различных типов.
Язык C# поддерживает операции явного и неявного преобразования типов, причём эти операции могут быть перегружены в пользовательских типах. При этом желательно, чтобы перегружаемые операции преобразования имели простую семантику и работали на сходных множествах значений.
Для выполнения взаимных преобразований данных базовых типов1 предназначен статический класс System.Convert. Этот класс содержит набор методов вида ToИмяТипа(), где ИмяТипа является именем CLR для базовых типов. Каждый такой метод перегружен и принимает аргумент любого базового типа. Выполнение метода может быть успешным или генерировать исключения InvalidCastException, FormatException, OverflowException.
byte x = Convert.ToByte("123"); // x = 123
bool y = Convert.ToBoolean(10.5); // y = true
int z = Convert.ToInt32(DateTime.Now); // InvalidCastException
Класс Convert также содержит методы для взаимных преобразований массива байт в строку (или массив символов) в формате Base-64:
var data = new byte[5] {10, 240, 100, 3, 90};
Console.WriteLine(Convert.ToBase64String(data)); ); // CvBkA1o=
var buffer = Convert.FromBase64String("ax2s732k");
Отметим, что для унификации операций преобразования все базовые типы явным образом реализуют интерфейс System.IConvertible. Это интерфейс содержит набор методов ToИмяТипа(), где ИмяТипа ‑ имя CLR для базовых типов. Каждый такой метод принимает параметр типа IFormatProvider. При реализации IConvertible базовые типы просто вызывают соответствующие методы класса Convert.
Статический класс System.BitConverter содержит набор методов для преобразования переменной числового или булевского типа в массив байт, а также методы обратного преобразования. Подобные преобразования полезны при низкоуровневой работе с потоками данных:
byte[] data = BitConverter.GetBytes(10567);
int x = BitConverter.ToInt32(data, 0);
Важными видами преобразований являются получение строкового представления объекта и получение объекта из строки. Для получения строкового представления объекта можно использовать виртуальный метод ToString(), определённый в классе System.Object. Однако часто требуется предоставить возможность выбора формата представления и учесть региональные стандарты. Для этой цели предназначен интерфейс System.IFormattable, который реализуют числовые типы, структура DateTime, класс Enum и некоторые другие типы:
public interface IFormattable
{
string ToString(string format, IFormatProvider formatProvider);
}
Параметр format – это строка, сообщающая способ форматирования объекта. Многие типы различают несколько строк форматирования. Например, DateTime поддерживает: строку "d" ‑ для дат в кратком формате, "D" ‑ для дат в полном формате, "G" ‑ для дат в общем формате, "M" ‑ в формате «месяц/день», "T" ‑ для времени и т. д. Все числовые типы поддерживают: "C" ‑ для валют, "D" ‑ для десятичных, "E" ‑ для научных, "F" ‑ для чисел с фиксированной точкой, "G" ‑ общий формат, "P" ‑ для процентов, "X" ‑ для шестнадцатеричных чисел. Числовые типы также поддерживают шаблоны форматирования, которые позволяют методу ToString() отобразить нужное количество цифр, место разделителя дробной части, количество знаков в дробной части и т. д. (полную информацию о строках форматирования смотрите в справке MSDN).
Региональные стандарты влияют на форматирование чисел, дат и времени. При формировании строки метод IFormattable.ToString() анализирует параметр formatProvider. Если он равен null, метод определяет региональные стандарты, связанные с текущим потоком выполнения, используя свойство Thread.CurrentThread.CurrentCulture с типом CultureInfo. Получив объект CultureInfo, ToString() считывает его свойства NumberFormat для форматирования числа или DateTimeFormat ‑ для форматирования даты (свойства имеют тип NumberFormatInfo и DateTimeFormatInfo соответственно1). NumberFormatInfo описывает группу свойств NegativeSign, CurrencyDecimalSeparator, CurrencySymbol, NumberGroupSeporator и т. п. Аналогично, у типа DateTimeFormatInfo имеются свойства Calendar, DayNames, DateSeparator, LongDatePattern, ShortTimePattern, TimeSeparator и т. п.
Параметр formatProvider имеет тип IFormatProvider:
public interface IFormatProvider
{
object GetFormat(Type formatType);
}
Реализация интерфейса IFormatProvider означает, что тип знает, как обеспечить учет региональных стандартов при форматировании. Метод ToString() вызывает IFormatProvider.GetFormat(), чтобы получить нужный объект для форматирования числа или даты2. Тип CultureInfo реализует IFormatProvider. Если нужно форматировать строку, скажем, для Вьетнама, следует создать объект CultureInfo и передать этот объект методу ToString():
DateTime dt = DateTime.Now;
// s = "07 Tháng Giêng 2010"
string s = dt.ToString("D", new CultureInfo("vi-VN"));
Если нужно получить строку, которая не отформатирована в соответствии с конкретными региональными стандартами, используется инвариантная культура, доступная через статическое свойство CultureInfo.InvariantCulture.
Чаще всего при получении строкового представления объекта нужно указать только формат, довольствуясь региональными стандартами, связанными с вызывающим потоком. Для упрощения работы во многие типы добавлены перегруженные версии метода ToString(), вызывающие IFormattable.ToString() с параметрами по умолчанию:
int x = 1024;
string s = x.ToString();
s = x.ToString("D3");
s = x.ToString(CultureInfo.InvariantCulture);
s = x.ToString("X", new CultureInfo("vi-VN"));
Тип может содержать дополнительные методы для получения строкового представления данных. Например, в DateTime определены методы ToLongDateString(), ToShortDateString(), ToLongTimeString(), ToShortDateString().
Для получения данных типа по строке обычно используются статические методы, которые по соглашению об именовании называются Parse() и TryParse(). Если преобразование из строки невозможно, метод Parse() генерирует исключение, а TryParse() возвращает значение false. Методы Parse() и TryParse() есть во всех примитивных типах, классе Enum, в типах для работы со временем и многих других типах. Обычно данные методы имеют перегруженные версии, принимающие в качестве параметра IFormatProvider. Некоторые типы дополнительно перегружают Parse() и TryParse() для более тонкой настройки преобразования:
int x = Int32.Parse("1024");
int z = Int32.Parse("A03", NumberStyles.HexNumber);
int y;
if (Int32.TryParse("4201", out y))
{
Console.WriteLine("Success");
}
DateTime dt = DateTime.Parse("13/01/2000 16:45:06");
В заключение рассмотрим вопрос преобразования строк. Платформа .NET способна поддерживать различные текстовые кодировки и наборы символов. Для этого используется базовый класс System.Text.Encoding и наследники этого класса – конкретные кодировки. Чтобы получить объект-кодировку можно использовать статический метод Encoding.GetEncoding() или статические свойства для наиболее популярных кодировок:
// используется имя кодировки по стандарту IANA (www.iana.org)
Encoding utf8 = Encoding.GetEncoding("utf-8");
// распространённую кодировку можно получить через свойство
Encoding ascii = Encoding.ASCII;
Основными методами каждого объекта-кодировки являются GetBytes() и GetString(). Первый метод служит для перевода строки или массива символов в массив байт (коды символов), второй метод делает обратное преобразование:
Encoding ascii = Encoding.ASCII;
byte[] asciiBytes = ascii.GetBytes("Sample text");
string s = ascii.GetString(asciiBytes);