34
Темы лекции: Перегрузка операций и обработка исключений. Практическое задание: Перегрузка операций и обработка исключений. Тренер: Игорь Шкулипа, к.т.н. Платформа .Net и язык программирования C#. Занятие 3

C# Desktop. Занятие 03

Embed Size (px)

Citation preview

Page 1: C# Desktop. Занятие 03

Темы лекции: Перегрузка операций и обработка исключений.

Практическое задание: Перегрузка операций и обработка исключений.

Тренер: Игорь Шкулипа, к.т.н.

Платформа .Net и язык программирования C#.

Занятие 3

Page 2: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 2

Перегрузка операций

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

public static Complex operator+ (Complex left, Complex Right)

{

}

Существует три типа перегружаемых операций:• Унарные операции с одним аргументом (++, --)• Бинарные операции с двумя аргументами (+, -, *, /)• Операции преобразования, которые определяют пользовательские

преобразования типов

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

public class Base{

public static operator+ (Base l, Base r){return l;}

}

public class Derived: Base{

// Ошибка компиляции

public static operator+ (Base l, Base r){return l;}

}

Page 3: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 3

Перегрузка операций

Перегруженные операции не должны изменять передаваемые импараметры. Для возвращения результата операции нужно создаватьновый экземпляр, содержащий результат и возвращать его.

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

Page 4: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 4

Операции, допускающие перегрузку

Бинарные операции сравнения должны быть реализованы парами.

Page 5: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 5

Интерфейс IComparable

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

CompareTo – метод, который сравнивает текущий экземпляр с другимобъектом того же типа и возвращает целое число, которое показывает,расположен ли текущий экземпляр перед, после или на той же позициив порядке сортировки, что и другой объект.

• Меньше нуля - данный экземпляр в порядке сортировки следуетперед obj.

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

• Больше нуля - данный экземпляр в порядке сортировки следуетпосле obj.

Object.Equals()

public virtual bool Equals( object obj );

Возвращает true , если заданный объект равен текущему объекту; впротивном случае — false.

Page 6: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 6

Object.GetHashCode()

Хэш-код — это числовое значение, используемое для идентификацииобъекта во время проверки равенства. Он также может служитьиндексом для объекта в коллекции.

Метод GetHashCode можно использовать в алгоритмах хэширования и такихструктурах данных, как хэш-таблицы.

Реализация метода GetHashCode по умолчанию не гарантируетуникальность возвращаемых для объекта значений. Более того, вплатформе .NET Framework не гарантируется реализация методаGetHashCode по умолчанию, также не гарантируется что, возвращаемыеэтим методом значения одинаковы в разных версиях .NET Framework.Следовательно, реализацию такого метода по умолчанию не следуетиспользовать для хэширования в качестве уникального идентификатораобъекта.

Object.ToString()

ToString является основным методом форматирования в .NET Framework.Он преобразует объект в строковое представление, таким образом,чтобы это подходило для отображения.

Page 7: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 7

Операции преобразования

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

Ключевое слово explicit служит для объявления оператора явногопреобразования пользовательского типа.

public static explicit operator string(Complex c);

public static implicit operator string(Complex c);

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

Page 8: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 8

Булевские операции

Некоторые типы могут встречаться в условных операторах или выступатьв качестве условий операторов циклов.

Для таких случаев можно перегрузить операции true/false, дляиспользуемого типа.

public static bool operator true(Complex c);

public static bool operator false(Complex c);

Page 9: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 9

Пример: Класс «Комплексное число»

public class Complex : IComparable

{

public double Re { get; set; }

public double Im { get; set; }

private double abs;

public double Abs

{

get

{

abs = Math.Sqrt(Re * Re + Im * Im);

return abs;

}

}

public Complex()

{ Re = 0; Im = 0; }

public Complex(double re)

{ Re = re; Im = 0; }

public Complex(double re, double im)

{ Re = re; Im = im; }

Page 10: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 10

Операции сложения/вычитания

public static Complex operator +(Complex left, Complex right)

{

return new Complex(left.Re + right.Re, left.Im + right.Im);

}

public static Complex operator -(Complex left, Complex right)

{

return new Complex(left.Re - right.Re, left.Im - right.Im);

}

public static Complex operator +(Complex left, double right)

{

return new Complex(left.Re + right, left.Im);

}

public static Complex operator -(Complex left, double right)

{

return new Complex(left.Re - right, left.Im);

}

public static Complex operator +(double left, Complex right)

{

return right + left;

}

public static Complex operator -(double left, Complex right)

{

return new Complex(left – right.Re, right.Im);

}

Page 11: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 11

Операции сравнения

public static bool operator ==(Complex left, Complex right)

{

return ((left.Im == right.Im) && (left.Re == right.Re));

}

public static bool operator !=(Complex left, Complex right)

{

return ((left.Im != right.Im) || (left.Re != right.Re));

}

Page 12: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 12

Object.Equals(), Object.GetHashCode()

public override bool Equals(object other)

{

bool result = false;

if (other is Complex)

{

var param = other as Complex;

if ((param.Im == this.Im) && (param.Re == this.Re))

result = true;

}

return result;

}

public override int GetHashCode()

{

return (int)this.Abs;

}

Page 13: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 13

IComparable.CompareTo(), Object.ToString()

int IComparable.CompareTo(object other)

{

if (other is Complex)

{

var param = other as Complex;

if (param.Abs > this.Abs) return -1;

if (param.Abs == this.Abs) return 0;

if (param.Abs < this.Abs) return 1;

}

return -1;

}

public override string ToString()

{

string strResult = "";

strResult += Re.ToString();

if (Im > 0) strResult += "+i" + Im.ToString();

else if (Im < 0) strResult += "-i" + (-Im).ToString();

else if (Im == 0) { };

return strResult;

}

Page 14: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 14

Операции преобразования

public static implicit operator string(Complex c)

{

string strResult = "";

strResult += c.Re.ToString();

if (c.Im > 0) strResult += "+i" + c.Im.ToString();

else if (c.Im < 0) strResult += "-i" + (-c.Im).ToString();

else if (c.Im == 0) { };

return strResult;

}

public static implicit operator Complex(double val)

{

return new Complex(val);

}

Page 15: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 15

Булевские операции

public static bool operator true(Complex c)

{

return ((c.Im != 0) || (c.Re != 0));

}

public static bool operator false(Complex c)

{

return ((c.Im == 0) && (c.Re == 0));

}

Page 16: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 16

Использование класса

class Program

{

static void Main(string[] args)

{

Complex c1 = new Complex();

Complex c2 = new Complex(2);

Complex c3 = new Complex(1, -1);

Console.WriteLine(c1.ToString());

Console.WriteLine(c2.ToString());

Console.WriteLine(c3.ToString());

Console.WriteLine((c1 + c2).ToString());

Console.WriteLine((c2 - c3).ToString());

Console.WriteLine((c3 + 1).ToString());

Console.WriteLine((1 - c3).ToString());

Console.ReadKey();

}

}

Page 17: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 17

Обработка исключений

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

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

Если такой обработчик не найден, то будет сгенерировано«необработанное исключение» и работа приложения будет прервана.

Page 18: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 18

Генерация и обработка исключений

Генерация исключений:

throw

Пример:throw new ArgumentOutOfRangeException();

Обработка исключений

try catch finally

Page 19: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 19

Примерint[] a=new int[99];

int b = 1, c=0;

try

{

a[100] = b / c;

}

catch (IndexOutOfRangeException ex)

{

Console.WriteLine(ex.Message);

}

catch (DivideByZeroException ex)

{

Console.WriteLine(ex.Message);

}

catch

{

Console.WriteLine("Неизвестное исключение");

}

finally

{

Console.WriteLine("Очистка");

}

Page 20: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 20

Примерint[] a=new int[99];

int b = 1, c=0;

try

{

a[100] = b / c;

}

catch (IndexOutOfRangeException ex)

{

Console.WriteLine(ex.Message);

}

catch (DivideByZeroException ex)

{

Console.WriteLine(ex.Message);

}

catch

{

Console.WriteLine("Неизвестное исключение");

}

finally

{

Console.WriteLine("Очистка");

}

Попытка деления на нуль.

Очистка

Page 21: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 21

Вложенные блоки исключенийtry

{

try

{

a[100] = b / c;

}

catch (IndexOutOfRangeException ex)

{

Console.WriteLine(ex.Message);

}

catch (DivideByZeroException ex)

{

Console.WriteLine(ex.Message);

throw new ArgumentOutOfRangeException();

}

catch

{

Console.WriteLine("Неизвестное исключение");

}

finally

{

Console.WriteLine("Очистка");

}

}

catch (IndexOutOfRangeException ex)

{

Console.WriteLine(ex.Message);

}

finally

{

Console.WriteLine("Очистка");

}

Page 22: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 22

Вложенные блоки исключений

Попытка деления на нуль.

Очистка

Заданный аргумент находится вне диапазона допустимых значений.

Очистка

Page 23: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 23

Класс Exception. Конструкторы

Имя Описание

Exception()Инициализирует новый экземпляр класса Exception.

Exception(String)Выполняет инициализацию нового экземпляра класса Exception, используя указанное сообщение об ошибке.

Exception(SerializationInfo, StreamingContext)

Инициализирует новый экземпляр класса Exception с сериализованными данными.

Exception(String, Exception)

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

Page 24: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 24

Класс Exception. Свойства

Имя Описание

DataВозвращает коллекцию пар "ключ-значение", предоставляющих дополнительную заданную пользователем информацию об исключении.

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

HResultВозвращает или задает HRESULT — кодированное числовое значение, присвоенное определенному исключению.

InnerExceptionВозвращает экземпляр объекта Exception, который вызвал текущее исключение.

MessageВозвращает сообщение, описывающее текущее исключение.

SourceВозвращает или задает имя приложения или объекта, вызывавшего ошибку.

StackTraceПолучает строковое представление непосредственных кадров в стеке вызова.

TargetSite Возвращает метод, создавший текущее исключение.

Page 25: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 25

Класс Exception. Методы

Имя Описание

Equals(Object)Определяет, равен ли заданный объект текущему объекту. (Унаследовано от Object.)

FinalizeПозволяет объекту попытаться освободить ресурсы и выполнить другие операции очистки, перед тем как объект будет утилизирован в процессе сборки мусора. (Унаследовано от Object.)

GetBaseExceptionПри переопределении в производном классе возвращает исключение Exception, которое является корневой причиной одного или нескольких последующих исключений.

GetHashCodeИграет роль хэш-функции для определённого типа. (Унаследовано от Object.)

GetObjectDataПри переопределении в производном классе задает сведения об исключении для SerializationInfo.

GetType

Возвращает тип текущего экземпляра в среде выполнения.

В XNA Framework 3.0 этот член наследуется от Object.GetType().

В Переносимая библиотека классов Переносимая библиотека классов этот член наследуется от Object.GetType().

В Приложения .NET для Магазина Windows Windows 8 этот член наследуется от Object.GetType().

MemberwiseCloneСоздает неполную копию текущего объекта Object. (Унаследовано от Object.)

ToStringСоздает и возвращает строковое представление текущего исключения. (Переопределяет Object.ToString().)

Page 26: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 26

SystemException

Определяет базовый класс для стандартных исключений в пространстве имен SystemНаследники:

Microsoft.SqlServer.Server.InvalidUdtExceptionAccessViolationExceptionActivities.ValidationExceptionAppDomainUnloadedExceptionArgumentExceptionArithmeticExceptionArrayTypeMismatchExceptionBadImageFormatExceptionCannotUnloadAppDomainExceptionCollections.Generic.KeyNotFoundExceptionComponentModel.Design.Serialization.CodeDomSerializerExceptionComponentModel.LicenseExceptionComponentModel.WarningExceptionConfiguration.ConfigurationExceptionConfiguration.Install.InstallExceptionContextMarshalExceptionData.DataExceptionData.DBConcurrencyExceptionData.OperationAbortedExceptionData.SqlTypes.SqlTypeExceptionDataMisalignedExceptionDeployment.Application.DeploymentExceptionDirectoryServices.AccountManagement.PrincipalExceptionDrawing.Printing.InvalidPrinterException

EnterpriseServices.RegistrationExceptionEnterpriseServices.ServicedComponentExceptionExecutionEngineExceptionFormatExceptionIdentityModel.LimitExceededExceptionIdentityModel.SecurityMessageSerializationExceptionIdentityModel.Tokens.SecurityTokenExceptionIndexOutOfRangeExceptionInsufficientExecutionStackExceptionInvalidCastExceptionInvalidOperationExceptionInvalidProgramExceptionIO.InternalBufferOverflowExceptionIO.InvalidDataExceptionIO.IOExceptionManagement.ManagementExceptionMemberAccessExceptionMulticastNotSupportedExceptionNotImplementedExceptionNotSupportedExceptionNullReferenceExceptionOperationCanceledExceptionOutOfMemoryExceptionPrinting.PrintSystemException

http://msdn.microsoft.com/ru-ru/library/system.systemexception.aspx

Page 27: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 27

ApplicationException

Это исключение возникает при возникновении устранимой ошибки приложения.

Наследники:

Microsoft.JScript.BreakOutOfFinallyMicrosoft.JScript.ContinueOutOfFinallyMicrosoft.JScript.JScriptExceptionMicrosoft.JScript.NoContextExceptionMicrosoft.JScript.ReturnOutOfFinallySystem.Reflection.InvalidFilterCriteriaExceptionSystem.Reflection.TargetExceptionSystem.Reflection.TargetInvocationExceptionSystem.Reflection.TargetParameterCountExceptionSystem.Threading.WaitHandleCannotBeOpenedException

http://msdn.microsoft.com/ru-ru/library/system.applicationexception.aspx

Page 28: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 28

Пользовательские исключения

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

public class InvalidDepartmentException : System.Exception

{

public InvalidDepartmentException()

: base() { }

public InvalidDepartmentException(string message)

: base(message) { }

public InvalidDepartmentException

(string message, System.Exception inner)

: base(message, inner) { }

}

Page 29: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 29

Генерация исключений

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

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

Page 30: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 30

Паттерн «Прототип»

Использует для создания новых объектов копию самого себя.

Паттерн Prototype (прототип) можно использовать в следующихслучаях:

◦ Система должна оставаться независимой как от процессасоздания новых объектов, так и от типов порождаемыхобъектов. Непосредственное использование оператора new вкоде приложения считается нежелательным.

◦ Необходимо создавать объекты, точные классы которыхстановятся известными уже на стадии выполненияпрограммы.

Page 31: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 31

Интерфейс ICloneable

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

Метод Clone() создает новый объект, являющийся копией текущегоэкземпляра.

Object.MemerwiseClone()

Метод MemberwiseClone для создания неполной копии создает новыйобъект, а затем копирует в него нестатические поля текущего объекта.Если поле относится к типу значения, выполняется побитовоекопирование полей. Если поле относится к ссылочному типу,копируются ссылки, а не объекты, на которые они указывают;следовательно, ссылки в исходном объекте и его клоне указывают наодин и тот же объект.

Page 32: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 32

Примерclass DeepStructure {

public int A { get; set; }

public int B { get; set; }

}

class CloneClass {

public int X { get; set; }

public int Y { get; set; }

public DeepStructure ds;

public CloneClass()

{

ds = new DeepStructure();

}

public override string ToString()

{

return

X.ToString() + " " +

Y.ToString() + " " +

ds.A.ToString() + " " +

ds.B.ToString() + " " +

ds.GetHashCode();

}

}

class ShallowCloneClass :

CloneClass, ICloneable

{

public object Clone()

{

return

(ShallowCloneClass)this.MemberwiseClone();

}

}

class DeepCloneClass :

CloneClass, ICloneable

{

public object Clone()

{

DeepCloneClass result =

new DeepCloneClass();

result.X = this.X;

result.Y = this.Y;

result.ds = new DeepStructure();

result.ds.A = this.ds.A;

result.ds.B = this.ds.B;

return result; ;

}

}

Page 33: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 33

Использованиеclass Program

{

static void Main(string[] args)

{

ShallowCloneClass sc1 = new ShallowCloneClass();

sc1.X = 1; sc1.Y = 2; sc1.ds.A = 3; sc1.ds.B = 4;

ShallowCloneClass sc2 = (ShallowCloneClass)sc1.Clone();

Console.WriteLine(sc1.ToString());

Console.WriteLine(sc2.ToString());

DeepCloneClass dc1 = new DeepCloneClass();

dc1.X = 1; dc1.Y = 2; dc1.ds.A = 3; dc1.ds.B = 4;

DeepCloneClass dc2 = (DeepCloneClass)dc1.Clone();

Console.WriteLine(dc1.ToString());

Console.WriteLine(dc2.ToString());

Console.ReadKey();

}

}

1 2 3 4 27226607

1 2 3 4 27226607

1 2 3 4 42549079

1 2 3 4 66790640

Page 34: C# Desktop. Занятие 03

http://www.slideshare.net/IgorShkulipa 34

Лабораторная работа №3. Перегрузка операций

• Создать класс «Квадратная матрица». Реализовать конструкторы дляслучайной генерации матриц.

• Выполнить перегрузку операций (+, -, *, >, < >=, <=, ==, !=,приведения типов, true, false, нахождение детерминанта, обратнаяматрица).

• Реализовать методы ToString(), CompareTo(), Equals(), GetHashCode().

• Реализовать для класса паттерн «Прототип» с глубоким копированием.

• Создать пользовательские классы исключений и реализовать ихобработку.

• Реализовать тестовое приложение «Матричный калькулятор» длядемонстрации работы созданного класса.