Учебные материалы по математике | Использование обработчиков исключений | Matematiku5
Вузы по математике Готовые работы по математике Как писать работы по математике Примеры решения задач по математике Решить задачу по математике online

Использование обработчиков исключений


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

Коды программ

//Задача: Описать класс РАЦИОНАЛЬНЫЕ ЧИСЛА

using System; //стандартная библиотека — ввод-вывод, базовые классы

using tInteger=System. Int32;

namespace Fraction //логически связанное определение имён (Пространства имён (namespace) предоставляют возможность логической взаимосвязи классов и других типов)

{

class сFraction

{//поля — см. далее Сокрытие данных (set, get- подход)

public tInteger numerator; //числитель

public tInteger denominator;// знаменатель

//не в нормализованном виде, если нужно — напиши метод

//методы:

//консольный ввод и вывод

private tInteger ReadInt(string s)

{

Console. WriteLine(s); //выводим на консоль информацию, которая содержалась в s

string input = Console. ReadLine(); // нет параметров, т. к. системный оператор

return Int32.Parse(input); // преобразование типов(читается строковое, а преобразуется в int)

}

public void read(string s)

{

Console. WriteLine(s);

numerator = ReadInt("Введите числитель: ");

denominator = ReadInt("Введите знаменатель: ");

}

private void WriteInt(string s, Int32 x)

{

Console. WriteLine(s);

Console. WriteLine(x. ToString()); //возвращает строку, представляющую текущий объект.

}

public void write(string s)

{

Console. WriteLine(s);

WriteInt("Числитель:", numerator);

WriteInt("Знаменатель:", denominator);

Console. ReadKey(); //задержка — получает следующий нажатый пользователем символ или функциональную клавишу. Нажатая клавиша отображается в окне консоли.

}

public void assign(сFraction a)//присваивание значений — "клонирование"

{

this. numerator = a. numerator;

this. denominator = a. denominator;

}

public void add(сFraction a) //добавить к this

{

this. numerator = this. numerator * a. denominator + a. numerator * this. denominator;

this. denominator = a. denominator * this. numerator;

}

public void subtract(сFraction a) //вычесть из this

{

this. numerator = this. numerator * a. denominator — a. numerator * this. denominator;

this. denominator = a. denominator * this. numerator;

}

public void multiply(сFraction a) //домножить

{

this. numerator = this. numerator * a. numerator;

this. denominator = a. denominator * this. denominator;

}

public void divide(сFraction a)//поделить

{

this. numerator = this. numerator * a. denominator;

this. denominator = this. denominator * a. numerator;

}

} //cFraction

class Program

{//программа — запускалка

//метод:

static void Main()

{

//сложение двух дробей y<—y+x

сFraction y, x; //указатели

x = new сFraction(); // вызов конструктора (выделение памяти)

y = new сFraction();

y. read("Введите первое слагаемое:");

x. read("Введите второе слагаемое:");

y. add(x);

y. write("Сумма равна:");

}

}// Program

}// Fraction

//Задача: Черепашья графика. Простая модель управления роботом-черепашкой, которая рисует на дискретной сетке.

using System;

using System. Collections. Generic;

using System. Linq;

using System. Text;

namespace Turtle//логически связанное определение имён

{

enum tColor {red, green, blue} //перечисляемый тип, состоящий из цветов

class cCell

{

protected internal tColor Color; // определение переменной Color типа tColor

//set-get:

public tColor GetColor() {return Color;}

cCell (tColor Color) {this. Color= Color;} // конструктор

} //class cCell

class cGrid //сетка

{

protected int Dim; //размерность

public int GetDim() {return Dim;}

protected internal cCell [,] Grid; //сама сетка(массив Grid) типа cCell (т. е. перечисляемого типа {red, green, blue})

// текущая позиция

protected internal int CurrentX; //, где internal означает то, что доступ ограничен текущей сборкой, а protected означает, что доступ ограничен содержащим классом или типами, которые являются производными от содержащего класса.

protected internal int CurrentY;

public int GetCurrentX() {return CurrentX; }

public int GetCurrentY() {return CurrentY; }

protected void Move (int x, int y )

{

//модульная арифметика (выход за границы)

CurrentX+=x; //эквивалентно выражению CurrentX = CurrentX + x

CurrentY+=y;

} // Move

cGrid (int Dim, tColor Color) //конструктор

{

this. Dim= Dim;

CurrentX=0;

CurrentY=0;

Grid= new cCell [Dim, Dim];

for (int i= 0; i<Dim; i++)

for (int j=0; j<Dim; j++)

Grid [i, j].Color= Color;

}

}

class TurtleGraphics: cGrid

{

//поля

public bool PenDown;// состояние пера — карандаш

public tColor PenColor;

public void GoUp()

{

Move(0,1);

if (PenDown) Grid[CurrentX, CurrentY].Color = PenColor;

}//PenGoUp

public void GoRight()

{

Move(1,0);

if (PenDown) Grid[CurrentX, CurrentY]. Color = PenColor;

}//PenRight

public void GoLeft()

{

Move(-1,0);

if (PenDown) Grid[CurrentX, CurrentY]. Color = PenColor;

}//PenLeft

public void GoDown ()

{

Move(0,-1);

if (PenDown) Grid[CurrentX, CurrentY]. Color = PenColor;

}//PenDown

}//class TurtleGraphics: cGrid

class Program

{ //запускалка

static void Main ()

{

}

}//class Program

}//namespace TurtleGraphics

// Компонентно-ориентированное программирование

//Задача: сложная иерархия животных, основанная на разной реализации строения, по передвижению

using System;

using System. Collections. Generic;

using System. Linq;

using System. Text;

using System. Threading. Tasks;

namespace Hierarchy

{

class cAnimals

{

protected string Name;

public void SetName(string x)

{

this. Name = x;

}

public string GetName()

{

return Name;

}

public cAnimals()

{

}

public cAnimals(string x)

{

this. Name = x;

}

}

class cMammals : cAnimals

{

}

class cFishes : cAnimals

{

}

class cBirds : cAnimals

{

}

//Разница между интерфейсами и абстрактными классами

//предок обязан/ может дать реализацию

//иными словами, здесь интерфейс не часть класса, но частный случай — абстрактный класс, наследование которого обязывает к реализации

abstract class FlyAble

{

public abstract void Fly();

}

//интерфейсы: только заголовки методов без модификаторов (public по умолчанию)

//в частности, нет полей (но может быть set-get) и невозможна инициализация

//движение с переменной скоростью

interface IMoveAble

{

void SetSpeed(int x);

int GetSpeed();

}

//вносится коллизия имён для демонстрации проблем множественного наследования

//ошибка проектирования?

//см. далее также обсуждение конфликта реализации и способы разрешения (склеивание, переименование)

interface IFlyAble : IMoveAble

{

void Fly();

}

interface IRunAble : IMoveAble

{

void Run();

}

interface ISwimAble : IMoveAble

{

void Swim();

}

class Elephant : cMammals, IRunAble, ISwimAble

{

//явное описание интерфейса- реализация:

void IRunAble. Run()

{

//выполнение метода:

Console. WriteLine("Elephant" + GetName() + "runs");

}

void ISwimAble. Swim()

{

//выполнение метода

Console. WriteLine("Elephant" + GetName() + "swims");

}

public Elephant()

{

}

public Elephant(string x)

{

this. Name= x;

}

//разрешение коллизии — "склеивание"

void IMoveAble. SetSpeed(int x)

{

}

int IMoveAble. GetSpeed()

{

return 0;

}

//иной вариант — переименование

//реализуем как закрытие, открываем под другими именами

// см. Duck

} //class Elephant

class Dolphin : cMammals, ISwimAble

{

//Явное описание интерфейса (реализация)

void ISwimAble. Swim()

{

//выполнение метода

}

void IMoveAble. SetSpeed(int x)

{

}

int IMoveAble. GetSpeed()

{

return 0;

}

} //class Dolphin

class Duck : cBirds, ISwimAble, IRunAble, IFlyAble

{

//Явное описание интерфейса-реализация:

void ISwimAble. Swim()

{

//Выполнение метода

}

void IRunAble. Run()

{

//выполнение метода

}

void IFlyAble. Fly()

{

//выполнение метода

}

void IMoveAble. SetSpeed(int x)

{

}

int IMoveAble. GetSpeed()

{

return 0;

}

}//class Duck

class Program

{

// запускалка

static void Main()

{

Elephant E1 = new Elephant();

E1.SetName("John");

//E1.Run_Method(); //ошибка — нужно явно выбирать интерфейс

((IRunAble)E1).Run(); //ok

IRunAble E2 = E1;

E2.Run(); // ok

//E2.SetName("???"); //ошибка

// объявление объекта интерфейсного класса

IRunAble E = new Elephant("Pete");

//E. SetName("???"); //ошибка

// объект, функционирующий по правилам метода

E. Run();

ISwimAble obj_Dolphin = new Dolphin();

obj_Dolphin. Swim;

ISwimAble obj_Duck_1= new Duck();

obj_Duck_1.Swim;

IRunAble obj_Duck_2= new Duck();

obj_Duck_2.Run();

IFlyAble obj_Duck_3= new Duck();

obj_Duck_3.Fly();

Console. ReadKey();

}

}// class Program

} //namespace Hierarchy

// Задача: динозавры и блохи

using System; // стандартные операции (часть языка)

using System. Collections. Generic;

using System. Linq;

using System. Text;

namespace Animals // определение имён

{

class cAnimal

{

//поля:

protected string Name;

public virtual string GetName() // get-метод виртуальный, т. к. он переопределяемый (для различныхклассов он будет возвращать не только имя, которое есть у всех, но и род, который у всех различен)

{

return "Animal" + Name; // род и имя животного

}

public cAnimal() //конструктор по умолчанию приходится переопределять, чтобы он был доступен

{

}

public cAnimal(string ThatAnimal) //конструктор

{

this. Name = ThatAnimal; // создаётся животное с каким-то именем (своим прозвищем)

}

//методы(cAnimal):

//virtual — допустимо переопределение в производном классе

public virtual void Move() //описание метода "Двигаться" для животных

{

Console. WriteLine(GetName() + "moves");

}

public virtual void Cry() // описание метода "Кричать" для животных

{

Console. WriteLine(GetName() + "cries");

}

public virtual void Bite(cAnimal ThatAnimal) // описание метода "Кусать" для всех животных в целом

{

Console. WriteLine(GetName() + "bites" + ThatAnimal. GetName()); // животное(род, имя), которое мы описываем, кусает другое животное(род, имя) (т. е в качестве параметра ссылка на другое животное )

}

//пример — вызов "вперёд" виртуальных методов из невиртуального

public void Attacks(cAnimal ThatAnimal) // описание метода "нападать" для животных в целом (это невиртуальный метод- переопределять его запрещено, т. е. в потомках он изменяться не может)

{

// метод Attacks вызывает виртуальный метод

Console. WriteLine(this. GetType() + "attacs" + ThatAnimal. GetName()); //нападение одного животного на другое

//нападение заключается в:

this. Move(); //животное передвигается

this. Bite(ThatAnimal); // кусает другое животное

ThatAnimal. Cry(); // то животное кричит (больно же)

ThatAnimal. Move(); // и убегает

}

}//class cAnimal

//класс "cDinosaur" наследник класса "сAnimal"

public class cDinosaur : cAnimal

{

public cDinosaur() //конструктор по умолчанию (при наследовании без конструктора по умолчанию выдаётся ошибка)

{

}

public cDinosaur(string ThatName) //конструктор

{

this. Name = ThatName;

}

//методы, которые добавляются к наследуемым методам (доопределение предыдущих методов для динозавров):

//модификатор override требуется для расширения или изменения абстрактной или виртуальной реализации унаследованного метода

public override string GetName() // переопределённый по отношению к животным

{

return "Dinosaur" + Name; //род и имя животного

}

public override void Cry() //переопределение метода "Кричать" для динозавров

{

Console. WriteLine(GetName() + "cries r-r!");

}

public void Growl() //описание метода "рычать" для динозавров — невиртуальный метод (для динозавров и всех его потомков не будет изменяться)

{

Cry();

}

public override void Move() //описание метода "двигаться" для динозавров

{

Console. WriteLine(GetName() + "runs");

}

} //class cDinosaur

class cTRex : cDinosaur

{

public cTRex() // конструктор по умолчанию

{

}

public cTRex(string ThatName) // конструктор

{

this. Name = ThatName;

}

public override string GetName()

{

return "TRex" + Name; // род и имя животного

}

public override void Cry() // переопределение метода "кричать" для динозавров

{

Console. WriteLine(GetName() + "cries R-R-R");

}

//обработка событий — слушатель/listener события FleaJumpEvent

private cFlea FleaJumpSender; // Flea To Listen To;- поле, в котором хранится ссылка на блоху

public void SetFleaJumpSender(cFlea x) // получает эту ссылку на эту блоху

{

FleaJumpSender = x; // запомнить источник события

//Итак, блоха нужна для того, чтобы достать лист, который при ней хранится (список слушателей)

FleaJumpSender. FleaJumpEventList += new cFlea. FleaJumpEventHandler(TRexFleaJumpEventHandler);// добавить в список ссылку на свой обработчик

// new — создаётся копияновой переменной функционального типа, который описан. Потом новое значение этого типа добавляется в список

// += — это бинарное присваивание (т. е. имя списка и в левой и в правой части присваивания)

// аналогично можно отписаться от подписки "-="

}

public void TRexFleaJumpEventHandler(cFlea Sender)

{

Console. WriteLine(GetName() + "afraid of" + Sender. GetName() + "jumping");

}

} // class cTRex

// класс "Flea" наследник класса "cAnimal"

class cFlea : cAnimal //производный класс "Блоха"

{

public cFlea() // конструктор по умолчанию

{

}

public cFlea(string ThatName) //конструктор

{

this. Name = ThatName;

}

//методы:

public override string GetName()

{

return "flea" + Name; // род и имя животного

}

public override void Move() // описание метода "двигаться" для блох

{

Console. WriteLine(GetName() + "jumps");

OnFleaJump(); // кратный вызов

}

public override void Cry() //описание метода "плакать"для блох

{

Console. WriteLine(GetName() + "cries Pi-pi"); //блоха

}

//обработка событий — источник/ sender

// организация обработки события FleaJumpEvent

public delegate void FleaJumpEventHandler(cFlea Sender); // типизированная ссылка на функцию — обработчик — заголовок

//-объявление функционального типа с именем FleaJumpEventHandler(типизированной ссылкой, но не на тип данных, а на функцию),где EventHandler — пользовательское соглашение — обработчик событий, а FleaJump-прыжок блохи

//delegate-функциональный тип, где к этому типу относятся любые функции, которые на вход принимают параметр типа блоха (т. е. cFlea Sender), которые возвращают функции

//Таким образом, к этому типу относятся все функции с определённым списком параметров

public event FleaJumpEventHandler FleaJumpEventList; // связь имени события с его обработчиками (реализация — список ссылок на обработчики

//event — событие — объявление переменной списка ссылок ранее объявленного типа

//список называется FleaJumpEventList, содержит он ссылки типа FleaJumpEventHandler

//кратный вызов — применение списка объявленного к нужному аргументу (обработчиков)

protected virtual void OnFleaJump() //protected, т. к. события не должны вызываться извне (т. е. эти события происходят внутри)

//OnFleaJump — по прыжку блохи- стандартное соглашение для методов такого назначения

{ // проверяется пустой ли список

if (FleaJumpEventList!= null) FleaJumpEventList(this); // если список непустой, то применяем список к this (т. е. блоха в качестве сообщения пересылает ссылку на себя),

//передавая значения полей

// Таким образом, не функция применяется к аргументу, а список функциональных ссылок (т. е. по ссылкам "дёргаются" функции, которые применяются поочерёдно к списку аргументов)

}

//теперь везде, где прыгает блоха, вызывается метод OnFleaJump

//OnFleaJump нужно вызвать в методе Move

} //class cFlea

class cProgram

{

static void Main()

{

cDinosaur Dino = new cDinosaur("Dino"); // создаём нового динозавра с именем Dino

cFlea Bug = new cFlea("Bug");// создаём новую блоху с именем Bug

Bug. Attacks(Dino); // полиморфный вызов — неявное уточнение типа cAnimal — блоха атакует динозавра

Console. WriteLine("______________________");

// аналогично

// Dino. cAnimal x;

// x=Dino; // уточнение типа не требует явного преобразования типа

// Bug. Attacks(x);

// отследи вызов последней реализации

cTRex Rex = new cTRex("Rex");

Bug. Attacks(Rex);

Console. WriteLine("______________________");

//обработка событий

cTRex AnotherRex = new cTRex("Another Rex");

Rex. SetFleaJumpSender(Bug); //вызывается метод set, в котором говорится от том, чтобы Rex слушал Bug

AnotherRex. SetFleaJumpSender(Bug);

Bug. Move(); //в этом методе есть OnFleaJump, который вызывает методы всех динозавров

Console. ReadKey(); //задержка

//Распечатываем имя динозавра, говорим, что этот динозавр боится прыжков конкретной блохи (выдаётся имя конкретной блохи)

}

}

}

// Задача: Организация обработки исключения

using System;

using System. Collections. Generic;

using System. Linq;

using System. Text;

using System. Threading. Tasks;

namespace ConsoleApplication1

{

class MyException : Exception // класс Exception- возможность получать пользоватеьские исключения

{

string Info; // некая информация об ошибке (исключительной ситуации)

public MyException(); // конструктор по умолчанию

public MyException(string Message) // конструктор для порождения ошибок

{

}

class ExceptionHandlingPattern //стандартная схема обработки исключительных ситуаций

{

//Заглушки. По умолчанию параметр — текущее состояние

//В конкретной ситуации — относящаяся к ней часть

private void MakeJob() { } // сделать некую работу

private void MakeOtherJob() { } // продолжить работу

private bool CheckState() { return true; } // проверить состояние

private void CorrectState() { Console. WriteLine("Попытка самостоятельно исправить ситуацию"); }//исправить состояние

public void TryToMakeJob() //

{

bool Success; //успех выполнению

bool Danger; //риск не выполнения

int MaxCount = 0; //максимальное число попыток выполнения

int Count = 0; // фактическое число попыток выполнения

do

{

Success = true;

try

{

MakeJob();

Danger = CheckState(); //возможно ли продолжение

if (Danger)

{

MyException ThisException = MyException(); //оформирование исключения

throw (ThisException);

}

MakeOtherJob(); //нормальное продолжение

}

catch (MyException me)

{

Success = false;

if (Count <= MaxCount)

{

Count++;

//level+=1; стек вызовов

CorrectState(); //корректировка ситуации

}

else

{

//level-=1 //откат

MyException ThisException = new MyException();

throw (ThisException);

}

}

}

while (!Success);

}

}//class

}

class Program

{

static void Main(string[] args)

{

//int level=0;

// конкретный пример- открыть и обработать файл

ExceptionHandlingPattern test = new ExceptionHandlingPattern();

try

{

test. TryToMakeJob();

}

catch (MyException ThisException)

{

// изменить начальное состояние

Console. WriteLine(ThisException. Message);

}

//catch() {} …catch() {}

finally

{// финализация. Получилось или нет — востановить среду}

}

}

}

}

Наташа

Автор

Наташа — контент-маркетолог и блогер, но все это не мешает ей оставаться адекватным человеком. Верит во все цвета радуги и не верит в теорию всемирного заговора. Увлекается «нефрохиромантией» и тайно мечтает воссоздать дома Александрийскую библиотеку.

Распродажа дипломных

 Скидка 30% по промокоду Diplom2020