
5.3. Специфические методы и поля простых типов
Кроме методов, унаследованных от общего базового класса Object, каждый простой тип имеет набор собственных методов и свойств. Рассмотрим те из них, которые являются достаточно общими и чаще всего применяются в программах.
Метод, без которого трудно обойтись в реальных программах, это метод Parse(), назначение которого - преобразовать текстовую строку в числовое или логическое значение. Полезность этого метода связана с тем фактом, что при общении с программой пользователь обычно вводит числовые значения (например, с клавиатуры), в виде последовательности символов, а в программе они должны быть представлены в виде машинных кодов соответствующих чисел.
Задача перекодирования символьной строки в код числового значения, во-первых, трудоемка для программирования, а во-вторых, не каждая последовательность символов может быть преобразована в числовое значение. Метод Parse(), определенный в каждом классе арифметических типов (Int32, Double...), позволяет автоматизировать решение задачи распознавания "правильных" записей числовых значений и задачи их преобразования в числа. Метод Parse() убирает из строки лишние пробелы слева и справа и незначащие левые нули.
Следующая программа иллюстрирует применение метода к строковым литералам, представляющим числовые значения:
// 05_02.cs - метод Parse()
static void Main02()
{
long row = long.Parse("18");
long col = System.Int64.Parse(" 000123 ");
Console.WriteLine("row + col = " + (row + col));
double x = double.Parse(" -000,314159e+1");
Console.WriteLine("x = " + x);
Console.WriteLine("Double.Parse(\" 0011 \") = " + Double.Parse(" 0011 "));
}
Обратите внимание, что метод Parse() является методом класса (статическим) и поэтому в его вызове нужно указать имя того класса, из которого он взят. Имя класса может быть или системным (в нашей программе System.Int64 и Double) или принятым в языке C# (long, double).
Результат выполнения программы:
row + col = 141
х = -3,14159
Double.Parse(" 0011 ") = 11
Строки (строковые константы-литералы), использованные в качестве аргументов метода Parse(), содержат ведущие и завершающие пробелы, а также незначащие левые нули. Такие отклонения в строковых (символьных) представлениях чисел считаются допустимыми. Следует обратить внимание на запятую, определяющую дробную часть числа от целой в символьном представлении. Это требование локализации, предполагающей, что в России используются не американские, а европейские правила записи вещественных чисел.
Примечание: В текстах программ на C# для отделения целой части вещественного числа от ее дробной части используется точка. При вводе и выводе, то есть во внешнем символьном представлении вещественных чисел, знак, разделяющий дробную и целую части, определяется локализацией исполняющей системы. Локализация может быть изменена настройкой.
При неверной записи числового или логического значения в аргументе метода Parse() генерируется исключение с названием System.Format.Exception. Так как мы еще не рассматривали механизм исключений, то примеры неудачных попыток применять метод Parse() к строкам с ошибками в записи чисел приводить преждевременно.
В .NET Framework 2.0 появился ещё один метод для преобразования строкового представления значения (арифметического, символьного, логического) в значение соответствующего простого типа. Этот метод перегружен и его варианты есть в разных классах. Например, в класс ординарных целых чисел входит вариант этого метода с таким заголовком:
static public bool TryParse (string, out int);
Метод анализирует строку, представленную первым параметром, и если её удаётся преобразовать в целочисленное значение, то это значение передаётся в точку вызова с помощью аргумента, заменяющего второй параметр. Кроме того метод имеет возвращаемое значение логического типа. При успешном преобразовании возвращается значение true. При неверном представлении в строке-аргументе значения соответствующего типа (того класса, для которого метод вызван) метод возвращает значение false.
Принципиальное отличие метода TryParse() от метода Parse() -отсутствие генерации исключений при неверных преобразованиях. Поэтому его можно использовать, не применяя механизма обработки исключений.
Чтобы привести пример, в котором будут показаны некоторые возможности метода TryParse(), нам придётся несколько расширить тот арсенал средств, которыми мы до сих пор пользуемся в примерах программ.
Начнём с модификатора out, который используется в спецификации второго параметра метода TryParse(). Таким модификатором снабжается параметр, с помощью которого метод возвращает в точку вызова некоторое значение. Аргумент, который будет подставлен на место этого параметра, должен быть пригоден для получения возвращаемого значения, и всегда снабжается в обращении к методу модификатором out. Таким аргументом может быть имя переменной.
Наиболее часто метод TryParse() применяется для анализа входных данных, вводимых пользователем с клавиатуры. Как мы уже показывали напримерах, последовательность символов, набранную на клавиатуре, можно "прочитать" с помощью метода
static public string Console.ReadLine();
Метод принадлежит классу Console. У метода ReadLine() параметры отсутствуют.
Метод "срабатывает" как только пользователь нажимает на клавиатуре клавишу ENTER. В точку вызова метод ReadLine() возвращает строку символов, набранную на клавиатуре. Обращение к методу ReadLine() можно использовать в качестве первого аргумента метода TryParse(). Вторым аргументом должна быть переменная того типа, значение которого мы планируем "прочитать" из входной строки.
Теперь, договорившись о новых средствах, приведём программу, которая читает из входного потока консоли (от клавиатуры) последовательность (строку) символов и анализирует её следующим образом. Если введено логическое значение (true или false), то для true нужно вывести символ '1', а для false - символ '0'. Если введённая последовательность символов не является изображением логического значения, то вывести знак '?'.
// 05_03.cs - Метод TryParse().
static void Main03()
{
bool bb;
char res;
Console.WriteLine("Введите логическое значение: ");
res = (bool.TryParse(Console.ReadLine(), out bb) == true) ? bb ? '1' : '0' : '?';
Console.WriteLine("res = = = > " + res);
}
Результаты нескольких выполнений программы:
Введите логическое значение: true<ENTER>
res = = = > 1
Введите логическое значение: false<ENTER>
res = = = > 0
Введите логическое значение: истина<ENTER>
res = = = > ?
В программе используется статический метод TryParse() класса bool. Первый аргумент - обращение к методу ReadLine() класса Console. Второй аргумент - переменная булевого типа с именем bb. Обращение к TryParse() входит в первый операнд тернарной условной операции ?:. Если возвращаемое методом значение равно true, то переменная bb получила одно из двух логических значений. В зависимости от конкретного значения bb символьной переменной присваивается '1' или '0' или '?'.
Результаты нескольких выполнений программы дополняют приведённые комментарии.
В каждый из классов, представляющих в C# предопределенные типы, входят несколько открытых статических константных полей, позволяющих оценить предельные значения переменных и констант соответствующего типа.
В классах целых типов таких полей два:
MaxValue - максимальное допустимое значение (константа);
MinValue - минимальное допустимое значение (константа).
В классах вещественных типов, кроме названных, присутствуют следующие статические константные поля:
Epsilon - наименьшее отличное от нуля числовое значение, которое может принимать переменная заданного типа; NaN - представление значения, которое не является числом, например, результат выполнения операции при делении нуля на нуль. Negativelnfinity - представление отрицательной бесконечности, например, при делении отрицательного числа на нуль. Positivelnfinity - представление положительной бесконечности, например, при делении положительного числа на нуль.
В следующей программе выводятся значения перечисленных констант, определенных в классах, соответствующих типам int и double.
// 05_04.cs - Константы и предельные значения
static void Main04()
{
Console.WriteLine("int.MinValue = " + int.MinValue);
Console.WriteLine("int.MaxValue = " + int.MaxValue);
Console.WriteLine("double.MinValue = " + double.MinValue);
Console.WriteLine("double.MaxValue = " + double.MaxValue);
Console.WriteLine("double.Epsilon = " + double.Epsilon);
Console.WriteLine("double.NaN = " + double.NaN);
Console.WriteLine("double.Positivelnfinity = " + double.PositiveInfinity);
Console.WriteLine("double.Negativelnfinity = " + double.NegativeInfinity);
double zero = 0.0, value = 2.7172;
Console.WriteLine("value/zero = " + value / zero);
Console.WriteLine("0.0/zero = " + 0.0 / zero);
}
Результаты выполнения:
int.MinValue = -2147483648
int.MaxValue = 2147483647
double.MinValue = -1,79769313486232E+308
double.MaxValue = 1,79769313486232Е+308
double.Epsilon = 4,94065645841247E-324
double.NaN = NaN
double.Positivelnfinity = бесконечность
double.Negativelnfinity = -бесконечность
value/zero = бесконечность
0.0/zero = NaN