Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по ООП (язык C#).pdf
Скачиваний:
190
Добавлен:
16.05.2015
Размер:
1.54 Mб
Скачать

Чернов Э. А.

- 15 -

Лекции по языку C# v 2.3

лями. Сдвиг вправо равносилен делению числа на два, но при этом положительные числа дополняются слева нулями, а отрицательные единицами. Это может привести к ошибке, поскольку при сдвиге вправо отрицательного числа на количество разрядов, равное разрядности числа, результат всегда будет состоять из одних двоичных единиц, независимо от начального значения числа. Если же переменная объявлена с модификатором unsigned, то при сдвиге вправо число слева дополняется нулями, то есть, искажение результата не происходит

Функции для ввода и вывода в языке C#

Функции для консольного ввода и вывода в языке C# существенно отличаются от аналогичных функций языка С++. Таких функций 4, и все они являются членами класса Console. Функции WriteLine и Write обеспечивают вывод на экран и отличаются тем, что функция WriteLine после вывода обеспечивает перевод вывода на новую строку на экране, а функция Write такой перевод не выполняет. Для ввода применяются функции ReadLine и ReadKey. Функция ReadLine обеспечивает ввод строки. Если содержимое строки является числом, то требуется преобразование строки в число. Такое преобразование выполняет функция Parse, которая записывается после точки после имени типа данных. Для обратного перевода в строку текста применяется функция ToString. Функция ReadKey позволяет ввести код нажатой клавиши, и она часто применяется для останова экрана пользователя после вывода на экран. Если эту функцию не записать, то экран быстро исчезнет, не дав возможности посмотреть, что было выведено. Ниже приведен пример.

double a, c;

// Объявление переменных

int b;

 

Console.WriteLine("Введите число");

// С переходом на новую строку

a = double.Parse(Console.ReadLine());

// Ввод с преобразованием

Console.WriteLine("Введите второе число");

b = int.Parse(Console.ReadLine());

// Ввод с преобразованием

c = a + b;

 

Console.WriteLine("Сумма {0} и {1} = {2}", a, b, c);

Console.ReadKey();

// Останов экрана

Вкавычках в круглых скобках записывается поясняющий текст и задается формат вывода. Для указания формата применяются пары фигурных скобок, в которых записываются целые числа, указывающие на порядок вывода переменных, имена которых записаны после кавычек. Отсчет начинается от нуля.

Впримере показано, что числа в фигурных скобках следуют подряд, что указывают на совпадение порядка вывода элементов с порядком записи имен переменных, список которых приведен после кавычек. Принципиально, изменяя порядок следования чисел в фигурных скобках, не изменяя порядка записи переменных в списке, можно изменять порядок вывода переменных на экран.

Всписке переменных для вывода можно применять арифметические выражения. Например, строку вывода из примера выше можно записать и так (в примере выше без использования переменной c):

Console.WriteLine("Сумма {0} и {1} = {2}", a, b, a + b);

Если требуется ввести числа и любые другие элементы в одной строке, в том числе и разнотипные (тип данных var будет описан ниже):

Чернов Э. А.

- 16 -

Лекции по языку C# v 2.3

var str = Console.ReadLine();

var result = str.Split(new[ ] {' ',';'}); foreach(var a in result)

Console.Write("{0} ", a);

Метод Split позволяет разбить введенную строку на отдельные элементы. Конструкция new[ ] указывает, что будет сформирован массив, количество элементов которого заранее неизвестно. В фигурных скобках в апострофах указывается символ, являющийся разграничителем между отдельными элементами во вводимой строке. Этот разграничитель может быть не один. В примере в качестве разграничителей заданы пробел и точка с запятой. Такая запись позволяет использовать любой из указанных разграничителей в любой последовательности, как отдельно, так и совместно. Переменная str является неявно типизированной. Тип данных var позволяет объявлять переменные, которые могут быть любого типа. Но особый интерес представляют таблицы, которые состоят из массивов строк. В этом случае переменной типа var является объект класса, которым является отдельная строка, а собственно таблица является массивом строк.

Управление форматом числовых данных:

При отображении данных на экране или при печати может потребоваться явное указание формы (формата) вывода, например, указание занимаемых позиций для числа при выводе таблиц, положение десятичной точки (запятой), количество цифр после десятичной точки и т. д. Для выполнения вывода в классе Console имеются две функции: WriteLine и Write. Они отличаются тем, что функция WriteLine после вывода заданных данных выполняет переход на новую строку, а функция Write этого не делает. Аргументы этих функций состоят из текстовой строки, заключенной в кавычки, после которой (не обязательно) перечисляются имена переменных для вывода. Если выводятся значения переменных, то в строке для каждой переменной в фигурных скобках указывается номер переменной списке.

Обычно номера в строке (в парах фигурных скобок) и позиции переменных в списке совпадают. Возможны также исключения. Например, можно повторить номер какой-либо переменной, тогда ее значение будет выведено повторно. Если же изменить порядок следования чисел в фигурных скобках, то значения переменных будут выводиться именно в этом порядке, а не в порядке записи переменных в списке.

Вместо имен переменных в списке могут использоваться арифметические выражения. Каждому такому выражению должен соответствовать номер в фигурных скобках.

Примеры.

Пусть объявлены переменные: int a = 3, b = 4;

Тогда операторы вывода

Console.WriteLine("Примеры вывода");// Строка формата выводит только текст

//В строке формата нумерация вывода в скобках и номера в списке совпадают

Console.WriteLine("Обычный порядок: сначала a = {0} потом b = {1}", a, b);

//В строке формата повтор номера в скобках, 2-я переменная не выводится

Чернов Э. А.

- 17 -

Лекции по языку C# v 2.3

Console.WriteLine("Повтор вывода a = {0} и a = {0} потом b = {1}", a, b);

//Нумерация вывода в скобках и номера в списке переменных не совпадают

Console.WriteLine("Обратный порядок: сначала b = {1} потом a = {0}", a, b);

//В списке переменных арифметическое выражение

Console.WriteLine("Если a = {0} и b = {1}, то сумма = {2} ", a, b, a + b);

Обеспечат вывод:

Для явного указания формата вывода после числа, указывающего на номер переменной для вывода, записывают двоеточие, после которого указывают форматный код. Если требуется жестко задать количество позиций для вывода значения переменной, то сначала после номера переменной записывают запятую, затем количество позиций. Если требуется форматный код, то он записывается после двоеточия, которое следует за количеством позиций для вывода.

Форматный код состоит из латинской буквы (заглавной или строчной), после которой записывается целое число, характеризующее данный формат. Ниже в таблице приведены форматные коды.

Код

Описание и назначение формата

Смысл числа после кода формата

 

 

 

 

Денежный. По умолчанию указы-

 

C

вается символ обозначения валю-

Задает общее количество десятичных разрядов.

ты для текущего регионального

 

стандарта.

 

D

Целочисленный

Задает количество цифр для представления числа.

Если число имеет меньше заданного количества

 

 

цифр, перед числом записываются нули.

E

Экспоненциальный

Задает количество цифр после десятичной запятой

(мантиссу). По умолчанию мантисса содержит 6 цифр

 

 

F

С фиксированной точкой

Задает количество цифр после запятой

 

 

 

 

 

Задается общее количество символов. В зависимости

 

 

от заданной длины представления числа выбирается

G

Обобщенный формат

экспоненциальный формат или формат с фиксиро-

ванной точкой (который может быть размещен в за-

 

 

 

 

данной длине). Если число целое, то оно выводится

 

 

без дробной части.

N

Использование разделителей ме-

Между группами из 3 цифр вставляется разделитель,

жду группами цифр числа

заданный региональными стандартами (для РФ про-

 

 

бел). По умолчанию дробная часть 2 цифры.

X

Шестнадцатеричный формат

Выводит целое число в шестнадцатеричной системе

счисления (без 0x, например, так: 124F8R16R)

 

 

 

 

Выводит число в виде процентов, например, 0.75 бу-

P

Процентный

дет выведено как 75.00%. Если число большое, то

 

 

между группами из 3 цифр вставляется разделитель.

Далее приведен фрагмент программы и скриншот выполнения этого фрагмента для демонстрации форматных кодов

int n = 53, m =148, k = 85000; double x = 345.66, y = 26, z = 0.65;

Чернов Э. А.

- 18 -

Лекции по языку C# v 2.3

Console.WriteLine(" Форматный код");

Console.WriteLine("0,4:D 1,10:F2 1,10:E2 1,10:G2 \n");

Console.WriteLine(" Форма вывода");

Console.WriteLine(" {0,4:D} {1,10:F2} {1,10:E2} {1,10:G2}", n, x, x, x); Console.WriteLine(" {0,4:D} {1,10:F2} {1,10:E2} {1,10:G2}", m, y, y, y);

Console.WriteLine("\n Форматный код");

Console.WriteLine(" 0,8:X 1,8:P 2:n\n");

Console.WriteLine(" Форма вывода");

Console.WriteLine(" {0,6:X} {1,10:p} {2:n}", k, z, 1000000000)

Примечание: Первая цифра в форматном коде – это номер переменной для вывода.

Во всех приведенных выше в скриншоте примерах выполнено выравнивание чисел вправо, поэтому слева от чисел вставляются пробелы для получения заданной ширины вывода.

Обработка исключительных ситуаций

На стадии выполнения программы по разным причинам могут возникать ошибки или непредвиденные проблемы. Это и плохой стиль программирования, и ошибки ввода и другие причины, которые можно классифицировать следующим образом:

1.Ошибки программирования, которые не выявляются на стадии компиляции программы, но которые могут возникнуть на стадии выполнения программы, например, выходы за границы массива, утечка памяти и тому подобное.

2.Ошибки конечного пользователя, которые возникают из-за неправильных действий пользователя. Чаще всего это ошибки ввода данных, превышение допустимых диапазонов чисел и т. д.

3.Ошибки готовности системы, которые возникают на стадии выполнения программы, и которые невозможно предусмотреть, например, попытка открыть не существующий файл, попытка входа в Интернет при отключенной сети и т. д.

Для пользователя было бы неудобно, если бы происходил выход из программы или выключение компьютера из-за неправильной буквы при наборе имени файла или другой аналогичной ошибки.

Перечисленные выше ситуации называются исключительными. На стадии выполнения программы выявляется причина появления исключительной ситуации, и либо пропускается выполнение оператора, вызвавшего ошибку, либо предлагаются меры по устранению причины ошибки с возможностью дальнейшего продолжения выполнения программы.

Чернов Э. А.

- 19 -

Лекции по языку C# v 2.3

Такая обработка является общей для многих языков программирования и называется структурированной обработкой исключений (Structured Exception Handling - SEN). Она предоставляет возможность вывода сообщения с описанием проблемы, а также обращения к Интернету для получения более подробного описания проблемы. Исключения могут быть стандартными или пользовательскими. Для стандартных исключительных ситуаций (деление на нуль, выход за границы массива, переполнение при выполнении арифметических операций и т. д.) предусмотрен перехват ошибки с предоставлением пользователю возможности ее устранения без выхода из программы. Исключительные ситуации пользователя некоторые значения или состояния трактуют как ошибки, которые обычно таковыми не являются и зависят только от конкретного приложения. Например, числа могут быть ограничены некоторым диапазоном, могут быть только положительными и т. п.

Если в программе записан блок для перехвата исключительной ситуации, то при ее появлении, либо этот блок предоставляет пользователю возможность исправить ошибку, либо пропускается выполнение оператора, вызвавшего ошибку. В любом из этих случаев выполнение программы не останавливается.

В языке С# для каждой исключительной ситуации должен быть создан класс. Все классы исключительных ситуаций должны быть производными от класса Exception, находящегося в пространстве имен System. Производным от него является класс SystemException, от которого наследуются все стандартные исключительные ситуации. Исключительные ситуации пользователя являются прямыми производными от класса Exception. Классы, созданные для обработки стандартных исключительных ситуаций, приведены в таблице ниже.

Класс исключений

Назначение

ArithmeticException

Базовый класс для исключений, происходящих при

 

арифметических операциях, например

 

System.DivideByZeroException

 

System.OverflowException.

ArrayTypeMismatchException

Вызывается при ошибке записи в массив элемента,

 

имеющего тип несовместимый с фактическим ти-

 

пом массива.

DivideByZeroException

Вызывается при попытке деления числа на нуль.

FormatException

Несоответствие формата, например, ввод вместо

 

числа буквы.

IndexOutOfRangeException

Вызывается, если при попытке обращения к масси-

 

ву задать индекс меньше нуля или выходящим за

 

границы массива.

InvalidCastException

Вызывается при ошибке явного преобразования из

 

одного типа в другой тип.

NullReferenceException

Вызывается, если при ссылке на отсутствующий

 

или пустой объект.

OutOfMemoryException

Вызывается при неудачной попытке выделения па-

 

мяти.

OverflowException

Вызывается при переполнении выполнения ариф-

 

метической операции, если не задан режим un-

 

checked.

StackOverflowException

Вызывается при переполнении стека из-за слишком

Чернов Э. А.

- 20 -

Лекции по языку C# v 2.3

 

 

 

Класс исключений

 

Назначение

 

большого уровня вложенных вызовов подпрограмм;

 

часто это указывает на ошибки реализации рекур-

 

сивных вызовов.

 

TypeInitializationException

Вызывается, когда при инициализации объекта ге-

 

нерируется ошибка, и отсутствует блок catch для ее

 

обработки.

 

Суть обработки исключительных ситуаций состоит в выявлении места в программе с потенциальным источником ошибки, при появлении которой управление будет передано некоторому блоку, несущему ответственность за устранение проблемы.

Для реализации обработки исключительных ситуаций блок операторов с потенциальным источником одной или нескольких ошибок заключается в фигурные скобки. Перед блоком записывается ключевое слово try (Попытка).

Один блок try может обрабатывать несколько исключительных ситуаций. Для каждой из таких ситуаций оформляется отдельный блок catch, в круглых скобках после которого записывается имя стандартной исключительной ситуации. Блоки catch записываются последовательно друг за другом сразу после конца блока try.

Если исключительную ситуацию (не стандартную и единственную) сформировал программист, то блок catch не содержит имени исключительной ситуации (нет круглых скобок после слова catch), но этот блок должен записываться последним.

Ниже в примере показана стандартная обработка деления на нуль и стандартная обработка переполнения. Добавлена также нестандартная обработка на запрет ввода отрицательных чисел. Для этого случая программист вызывает собственную обработку исключительной ситуации.

if (k < 0 || m < 0) throw new Exception();

//Исключение пользователя

Исключительную ситуацию можно объявить отдельно:

Exception ex = new Exception(); //

Затем ее вызвать оператором throw (ex);

Если исключительная ситуация вызывается программистом, то блок для ее обработки должен записываться последним.

Обычно ошибочный ввод можно выполнить только один раз. Если ошибка была обнаружена два раза, то она обработана не будет и будет выполнен аварийный останов программы.

Ниже представлена программа, в которой обработка исключительной ситуации заключена в цикл с целью повтора выполнения программы при вводе данных, которые приводят к возникновению исключительной ситуации. Однако количество повторений цикла ограничено. Для этого вставлен счетчик, значение которого сравнивается с заданным количеством повторений (attempts).

static void Main(string[ ] args)

{

int k = 0, m = 0, p = 0, count = 0, attempts = 3; // - attempts сколько попыток bool flag = true;//

Чернов Э. А.

- 21 -

Лекции по языку C# v 2.3

do

{

try

{

Console.WriteLine("Введите k и m"); k = int.Parse(Console.ReadLine());

if (k < 0) throw new Exception();// Исключительная ситуация пользователя m = int.Parse(Console.ReadLine());

p = (k + m) / (k - m); // Если k = m, деление на 0 flag = false;

}

catch (DivideByZeroException)//

{

count++;//

if (count >= attempts - 1) flag = false; // Количество попыток исчерпано else Console.WriteLine

("Деление на 0: k = {0} m = {1} повторите попытку с другими k и m", k, m);

}

 

catch

// Исключительная ситуация, заданная пользователем (k < 0)

{

 

Console.WriteLine

(" Введено k < 0, повторите ввод");

}

 

} while (flag);

 

if (count < attempts)

// Все нормально

Console.WriteLine("Ответ p = {0}", p);

else // Все попытки приводили к делению на 0

Console.WriteLine("Деление на 0, все попытки окончились");

Console.ReadKey();

// Останов экрана

}

Ниже представлен вывод программы при разных вариантах ввода. Нормальный ввод

После ввода возникло деление на нуль

Было выполнено 3 попытки ввода, и во всех была попытка деления на 0

Чернов Э. А.

- 22 -

Лекции по языку C# v 2.3

Обработка исключительной ситуации пользователя

Класс Exception обладает рядом свойств, позволяющих уточнить причину возникновения исключительной ситуации. Эти свойства, доступные только для чтения, приведены в таблице ниже.

Свойство

Data

HelpLink

InnerException

Message

Source

StackTrace

TargetSite

Значение

Это коллекция пар "ключ/значение", определяемая программистом, может предоставлять дополнительную информацию об исключении. По умолчанию эта коллекция является пустой Это свойство позволяет получать или устанавливать URL-адрес, по которому можно обратиться к справочному файлу или сайту с подробным описанием ошибки Это свойство предоставляет информацию о предыдущих внеш-

них исключениях, которые стали причиной текущего вложенного исключения.

Это свойство возвращает текст с описанием текущей ошибки. Текст можно задать с помощью конструктора с параметром для класса Exception.

Это свойство указывает на имя проекта, который привел к выдаче сообщения об ошибке. В языке CLR указывается сборка. Это свойство описывает последовательность вызовов, которая привела к возникновению исключения.

Это свойство возвращает имя подпрограммы, имя файла или тип объекта (подпрограмма – метод, структура и т. д.), которые сгенерировали выдачу сообщения.

В общем случае для обращения к свойствам класса Exception в круглых скобках заголовка catch для соответствующей исключительной ситуации объявляется объект этого класса, а через имя этого объекта можно получить значение свойства. Например, для обработки деления на нуль можно записать заголовок блока catch в виде:

catch (DivideByZeroException ex)

Чернов Э. А.

- 23 -

Лекции по языку C# v 2.3

Тогда вывод свойства TargetSite на экран обеспечит оператор

Console.WriteLine("Имя программы: {0}", ex.TargetSite);

Рассмотрим теперь пример с просмотром свойств исключительных ситуаций. Это вариант обработки исключительных ситуаций, при котором в заголовке блока catch объявляется объект класса Exception. Внутри блока выполняется вывод свойств данной конкретной исключительной ситуации для анализа.

Название исключительной ситуации (IndexOutOfRangeException) определяется автоматически. Другие виды исключительных ситуаций надо указывать явно.

Ниже приведена программа подсчета голосов. Задан список номеров кандидатов. При вводе номер кандидата используется в качестве индекса массива, а элемент является счетчиком (для него выполняется операции приращения на 1). Сколько раз был введен номер этого кандидата, столько за него подано голосов.

Установим специальное значение индекса (-20) для нормального завершения программы, для выхода из «вечного» цикл для нормального завершения программы.

static void Main(string[ ] args)

{

int n;

// № кандидата

int tot;

// Количество кандидатов

Console.WriteLine("\nВведите количество кандидатов"); tot = int.Parse(Console.ReadLine());

int [ ] ar = new int[tot]; // Объявление массива счетчиков while (true)

{

Console.WriteLine("\nВведите № кандидата"); try

{

n = int.Parse(Console.ReadLine());

if (n == -20) break;// № кандидата для выхода

ar[n - 1]++; // Индексы в массиве от 0, а номера от 1

}

catch (IndexOutOfRangeException ex)

{

Console.WriteLine("\nИмя программы: {0}", ex.TargetSite); Console.WriteLine("Файл определения класса : {0}",

ex.TargetSite.DeclaringType); Console.WriteLine("Тип члена : {0}", ex.TargetSite.MemberType);

Console.WriteLine("Сообщение : {0}", ex.Message); Console.WriteLine("Имя проекта : {0}", ex.Source);

Console.WriteLine("\nСтек: {0}", ex.StackTrace);

}

finally

{

// Эта блок будет выполняться всегда

}

}

Console.WriteLine("\nРезультаты голосования\n"); for (int i = 0; i < tot; ++i)

Console.WriteLine("Голосов за кандидата {0} {1} ", i + 1, ar[i]);

Чернов Э. А.

- 24 -

Лекции по языку C# v 2.3

Console.ReadKey();

}

Если бы не были бы предприняты меры по исключению проверки выхода за пределы допустимых значений индексов, то при вводе индекса, лежащего за пределами допустимых значений, будет выполнен аварийный останов программы с выдачей приведенного ниже сообщения. (Это вариант без блоков try и catch)

В аварийном сообщении имеется строка View Detail, которая позволяет локализовать исключительную ситуацию. Щелчок по этой строке выводит сообщение:

В приведенной программе вставлены блоки try и catch, поэтому на экран можно выводить свойства исключительной ситуации. В заголовке блока объявим переменную ex класса Exception. Через эту переменную можно обращаться к свойствам исключительной ситуации.

Пример распечатки этих свойств показан ниже. Эта распечатка появляется при вводе номера кандидата, выходящего за границу массива (номер кандидата больше заданного количества). При этом после вывода распечатки выполнение программы не останавливается, и продолжается голосование.

Чернов Э. А.

- 25 -

Лекции по языку C# v 2.3

Обратите внимание, вывод информации повторяется в окне View Detail, выполненный при аварийном завершении программы. В данном случае аварийного останова не происходит, а неправильный ввод игнорируется. (Русский язык в сообщениях был задан в операторах WriteLine).

И последнее, группу блоков обработки исключительной ситуации может завершать необязательный блок finally, который выполняется всегда, независимо от наличия или отсутствия исключительной ситуации

Покажем пример программы, в которой имеются: блок обработки исключительной ситуации, заданной пользователем, и блок finally. Пусть требуется построить для группы студентов гистограмму ответов на вопрос, как они собираются отвечать на вопросы на предстоящем экзамене. Ответов может быть 3:

1.Откуда-нибудь списать.

2.Получить ответ из Интернета.

3.Подготовиться к экзамену. Ниже представлен код программы. class Program

{

static void Main(string[] args)

{

int[] Gist = new int[3]; string st;

int d = 0;

bool flag = true; Console.Clear();

Console.WriteLine ("\n Как вы будете сдавать экзамен? \n" +

"1 - Спишу у кого-нибудь \n" +

"2 - Спрошу в Интернете \n" +

"3 – Подготовлюсь и сдам сам \n" +

"4 - Выход ");

Console.WriteLine("\n Выберите вариант ответа"); while (flag)

Чернов Э. А.

- 26 -

Лекции по языку C# v 2.3

{

try // Блок генерации исключительной ситуации

{

st = Console.ReadLine(); d = int.Parse(st);

if (d < 1 || d > 4) throw new Exception();// ;

}

catch //

{

Console.WriteLine("\n Ошибка! Такого \"" + d + "\" выбора нет"); // запись \""+ d+"\" выводит на экран число d в кавычках

d = 1;

}

finally

{

if (d == 4) flag = false;

else ++Gist[d - 1]; // Накопление гистограммы, индексы от 0

}

}

Console.Clear();

Console.WriteLine("\n Студенты обещают на экзамене \n" + "Сколько" + " Что сделают \n" +

Gist[0] + " – Спишут \n" +

Gist[1] + " - Получат ответ из Интернета \n" + Gist[2] + " - Ответят сами");

Console.ReadKey(); // Останов экрана

}

// от Main

}

// от class Program

Ниже представлен результат выполнения программы при запуске.

После социологического опроса результат может быть, например, таким.

Если блоков для обработки исключительных ситуаций пользователя требуется более одного, тогда создают пользовательские классы для обработки исключительных ситуаций.

Такой класс является производным от класса Exception и наследует доступные свойства и методы, которые при желании можно перегрузить. Однако в производном классе требуется переопределить конструкторы, определенные в базовом классе и необходимые для данного пользовательского класса для обработки данного исключения.

Чернов Э. А.

- 27 -

Лекции по языку C# v 2.3

Ниже приведен пример, в котором обрабатываются исключительные ситуации пользователя и обеспечивающий работу только с положительными числами и не пустыми строками.

В объявлении пользовательского класса конструктор этого класса определен через ссылку на конструктор базового класса. Если при объявлении класса Exception используется конструктор без параметров, то и ссылка на конструктор базового класса должна быть без параметров. В комментариях показано оформление конструктора с параметрами.

Показан пример описания пользовательского класса обработки исключения. В примере описано один дополнительный класс для обработки исключительной ситуации, вторая обработка (запрет ввода пустой строки) выполнена в блоке без параметров, но и для этой обработки можно оформить отдельный класс.

namespace Try_catch

{

// Описание пользовательского класса обработки исключения class OnlyPositiveNumbers : Exception

{

// Если список при объявлении исключения пуст public OnlyPositiveNumbers() : base() { }

//public OnlyPositiveNumbers(string str) : base(str) { } // Список не пуст

}

class Program

{

static void Main(string[] args)

{

//Объявление Exception с пустым конструктором

OnlyPositiveNumbers ex1 = new OnlyPositiveNumbers();

//Объявление Exception для конструктора с параметром

//OnlyPositiveNumbers ex1 = new OnlyPositiveNumbers

// ("Число должно быть > 0");

string str; int n = 0; try

{

Console.WriteLine("Введите число"); n = int.Parse(Console.ReadLine());

if (n < 0) throw ex1; Console.WriteLine("Введите строку"); str = Console.ReadLine();

if (str.Length == 0) throw new Exception();

}

catch (OnlyPositiveNumbers)

{

Console.WriteLine("Введено отрицательное число");

}

catch

{

Console.WriteLine("Введена пустая строка");

}

finally