SlideShare a Scribd company logo
Модуль 07 Перегрузка операторов
1
Ключевые слова преобразований
2
explicit
implicit
operator
3
Можно перегружать
Бинарные операторы: +, -, *, /, %, &, |, ^, <<, >>,
==, !=, <, >, <=, >=
Унарные операторы: +, -, !, ++, —, true, false
4
Нельзя перегружать
[] – функционал этого оператора предоставляют
индексаторы
() – функционал этого оператора предоставляют
методы преобразования типов
+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
краткие формы оператора присваивания будут
автоматически доступны при перегрузке
соответствующих операторов (+, -, * …).
5
БИНАРНЫЕ ОПЕРАТОРЫ
6
УНАРНЫЕ ОПЕРАТОРЫ
+, -, !, ++, —, true, false
7
ОПЕРАТОРЫ СРАВНЕНИЯ
[==, !=], [<, >], [<=, >=]
8
Перегрузка операторов отношения
== и <
9
Перегрузка операторов true и false
10
Перегрузка логических операторов
11
Операторы преобразования
12
ЯВНОЕ ПРЕОБРАЗОВАНИЕ
public static explicit operator
целевой_тип(исходный_тип v) {return значение;}
НЕЯВНОЕ ПРЕОБРАЗОВАНИЕ
public static implicit operator
целевой_тип(исходный_тип v) {return значение; }
16
ЗАКЛЮЧЕНИЕ
• Не злоупотребляйте ими
• Не используйте их неправильно
• Будьте очень осторожны

More Related Content

More from Yevgeniy Gertsen

модуль 11 структуры, перечисления
модуль 11 структуры, перечислениямодуль 11 структуры, перечисления
модуль 11 структуры, перечисления
Yevgeniy Gertsen
 
Модуль 10 Интерфейсы
Модуль 10 ИнтерфейсыМодуль 10 Интерфейсы
Модуль 10 Интерфейсы
Yevgeniy Gertsen
 
модуль 06 пространства имен
модуль 06 пространства именмодуль 06 пространства имен
модуль 06 пространства имен
Yevgeniy Gertsen
 
модуль 05 обработка исключений
модуль 05 обработка исключениймодуль 05 обработка исключений
модуль 05 обработка исключений
Yevgeniy Gertsen
 
модуль 03 строки
модуль 03 строкимодуль 03 строки
модуль 03 строки
Yevgeniy Gertsen
 
модуль 03 массивы
модуль 03 массивымодуль 03 массивы
модуль 03 массивы
Yevgeniy Gertsen
 
модуль 02 основы языка программирования c#
модуль 02 основы языка программирования c#модуль 02 основы языка программирования c#
модуль 02 основы языка программирования c#
Yevgeniy Gertsen
 
модуль 01 введение в платформу microsoft .net
модуль 01 введение в платформу microsoft .netмодуль 01 введение в платформу microsoft .net
модуль 01 введение в платформу microsoft .net
Yevgeniy Gertsen
 

More from Yevgeniy Gertsen (12)

модуль 11 структуры, перечисления
модуль 11 структуры, перечислениямодуль 11 структуры, перечисления
модуль 11 структуры, перечисления
 
Модуль 10 Интерфейсы
Модуль 10 ИнтерфейсыМодуль 10 Интерфейсы
Модуль 10 Интерфейсы
 
модуль 09-02
модуль 09-02модуль 09-02
модуль 09-02
 
модуль 09-01
модуль 09-01модуль 09-01
модуль 09-01
 
модуль 08
модуль 08модуль 08
модуль 08
 
модуль 06 пространства имен
модуль 06 пространства именмодуль 06 пространства имен
модуль 06 пространства имен
 
модуль 04
модуль 04модуль 04
модуль 04
 
модуль 05 обработка исключений
модуль 05 обработка исключениймодуль 05 обработка исключений
модуль 05 обработка исключений
 
модуль 03 строки
модуль 03 строкимодуль 03 строки
модуль 03 строки
 
модуль 03 массивы
модуль 03 массивымодуль 03 массивы
модуль 03 массивы
 
модуль 02 основы языка программирования c#
модуль 02 основы языка программирования c#модуль 02 основы языка программирования c#
модуль 02 основы языка программирования c#
 
модуль 01 введение в платформу microsoft .net
модуль 01 введение в платформу microsoft .netмодуль 01 введение в платформу microsoft .net
модуль 01 введение в платформу microsoft .net
 

Модуль 07 Перегрузка операторов

Editor's Notes

  1. Известно, что в Си-шарп существует ряд операторов для работы со встроенными типами данных. Это операторы «+», «-», «!», «==», «!=» и т.д. Например, бинарный оператор «+» выполняет операцию сложения над численными типами данных. Этот же самый оператор над строками выполняет конкатенацию (склеивание двух строк). Это происходит потому, что оператор «+» перегружен в классе String. Для перегрузки оператора служит ключевое слово operator, определяющее операторный метод, который, в свою очередь, определяет действие оператора относительно своего класса. Существуют две формы операторных методов (operator): одна - для унарных операторов, другая - для бинарных. Простыми словами, перегрузка оператора - это реализация своего собственного функционала этого оператора для конкретного класса. Перегрузка оператора реализуется похожим способом на перегрузку методов. Здесь используется ключевое слово operator.
  2. Перегрузка операторов – это мощная и недостаточно используемая (но часто неправильно используемая) возможность, способная сделать код более простым, а использование объектов - более интуитивно-понятным. Добавление нескольких простых перегруженных операторов в класс или структуру даст вам возможность: выполнять преобразования в/ из вашего типа (и) в другие типы производить математические/логические операции над вашим типом и над ним самим или над другими типами Ключевое слово explicit объявляет оператор преобразования определяемого пользователем типа, который должен быть вызван с помощью приведения. Ключевое слово implicit служит для объявления неявного оператора преобразования пользовательского типа. Этот оператор обеспечивает неявное преобразование между пользовательским типом и другим типом, если при преобразовании исключается утрата данных. Ключевое слово operator используется для перегрузки встроенного оператора или выполнения пользовательского преобразования в объявлении класса или структуры.
  3. Exmpl1 Бинарные операторы принимают два аргумента. Могут быть перегружены следующие операторы: +, -, *, /, %, &amp;, |, ^, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;. Примечание: Важно, чтобы вы не делали ничего неожиданного при использовании операторов, двуместных или других. Обычно эти операторы довольно логичны. Для начала рассмотрим +. Он обычно вычисляет сумму двух аргументов. Приведу пример перегрузки оператора «+» для сложения объектов класса деньги (Money). Деньги характеризуются количеством и валютой. Если добавлять рубли к рублям, то всё будет корректно. Но если необходимо суммировать доллары и рубли это уже нужно как-то обрабатывать. В случае разных валют можно просто выбросить исключение, что валюты разные, или же переводить одну валюту по курсу в другую и суммировать деньги в одной валюте.
  4. Унарные операторы принимают только один аргумент. Могут быть перегружены следующие операторы: +, -, !, ~, ++, --, true, false. Для большинства типов не нужно реализовывать все эти операторы, поэтому реализуйте только необходимые вам!  int a = 2, b = 3, c, d = 3;  c = a + ++b; // c = 6, сначала инкремент, потом сложение  с = a + d++; // c = 5, сначала сложение, потом инкремент Везде где можно использовать инкрементацию/декрементацию стоит это делать, так как она работает быстрее оператора сложения/вычитания.  int a = 2, b = 3;a += b; // равноценно выражению a = a + b;   a -= b; // равноценно выражению a = a - b;   a *= b; // равноценно выражению a = a * b;   a /= b; // равноценно выражению a = a / b;   a %= b; // равноценно выражению a = a % b;
  5. Операторы сравнения принимают два аргумента. Могут быть перегружены следующие операторы. [==, !=], [&amp;lt;, &amp;gt;], [&amp;lt;=, &amp;gt;=]. Они сгруппированы в квадратных скобках, так как их нужно реализовывать попарно. При использовании == and != также необходимо заменить Equals(object o) и GetHashCode().
  6. exmpl5 Операторы отношения, например == и &amp;lt;, могут также перегружаться, причем очень просто. Как правило, перегруженный оператор отношения возвращает логическое значение true и false. Это вполне соответствует правилам обычного применения подобных операторов и дает возможность использовать их перегружаемые разновидности в условных выражениях. Если же возвращается результат другого типа, то тем самым сильно ограничивается применимость операторов отношения.
  7. Exmpl6 Ключевые слова true и false можно также использовать в качестве унарных операторов для целей перегрузки. Перегружаемые варианты этих операторов позволяют определить назначение ключевых слов true и false специально для создаваемых классов. После перегрузки этих ключевых слов в качестве унарных операторов для конкретного класса появляется возможность использовать объекты этого класса для управления операторами if, while, for и do-while или же в условном выражении ?. Операторы true и false должны перегружаться попарно, а не раздельно. 
  8. Exmpl7 Как вам должно быть уже известно, в C# предусмотрены следующие логические операторы: &amp;, |, !, &amp;&amp; и ||. Из них перегрузке, безусловно, подлежат только операторы &amp;, | и !. Тем не менее, соблюдая определенные правила, можно извлечь также пользу из укороченных логических операторов &amp;&amp; и ||.
  9. Иногда объект определенного класса требуется использовать в выражении, включающем в себя данные других типов. В одних случаях для этой цели оказывается пригодной перегрузка одного или более операторов, а в других случаях — обыкновенное преобразование типа класса в целевой тип. Для подобных ситуаций в C# предусмотрена специальная разновидность операторного метода, называемая оператором преобразования. Такой оператор преобразует объект исходного класса в другой тип. Операторы преобразования помогают полностью интегрировать типы классов в среду программирования на C#, разрешая свободно пользоваться классами вместе с другими типами данных, при условии, что определен порядок преобразования в эти типы.
  10. Exmpl7 Существуют две формы операторов преобразования: явная и неявная.  где целевой_тип обозначает тот тип, в который выполняется преобразование; исходный_тип — тот тип, который преобразуется; значение — конкретное значение, приобретаемое классом после преобразования. Операторы преобразования возвращают данные, имеющие целевой_тип, причем указывать другие возвращаемые типы данных не разрешается. Неявное преобразование означает, что можно напрямую присваивать экземпляр одного типа другому. Если оператор преобразования указан в неявной форме (implicit), то преобразование вызывается автоматически, например, в том случае, когда объект используется в выражении вместе со значением целевого типа. ---- Если же оператор преобразования указан в явной форме (explicit), то преобразование вызывается в том случае, когда выполняется приведение типов. Для одних и тех же исходных и целевых типов данных нельзя указывать оператор преобразования одновременно в явной и неявной форме.
  11. Оператор неявного преобразования применяется автоматически в следующих случаях: когда в выражении требуется преобразование типов; методу передается объект; осуществляется присваивание и производится явное приведение к целевому типу. С другой стороны, можно создать оператор явного преобразования, вызываемый только тогда, когда производится явное приведение типов. На операторы преобразования накладывается ряд следующих ограничений:
  12. Помимо указанных выше ограничений, имеется ряд рекомендаций, которыми обычно руководствуются при выборе операторов явного или неявного преобразования. Несмотря на все преимущества неявных преобразований, к ним следует прибегать только в тех случаях, когда преобразованию не свойственны ошибки. Во избежание подобных ошибок неявные преобразования должны быть организованы только в том случае, если удовлетворяются следующие условия. Во-первых, информация не теряется, например, в результате усечения, переполнения или потери знака. И во-вторых, преобразование не приводит к исключительной ситуации. Если же неявное преобразование не удовлетворяет этим двум условиям, то следует выбрать явное преобразование.
  13. Если вы не использовали ее раньше, опробуйте ее в работе – она может оказаться для вас полезным инструментом. Не злоупотребляйте ими. Если оператор или преобразование точно никогда не понадобятся, или не очевидно, каким будет результат, не реализуйте его. Не используйте их неправильно. Можно сделать так, чтобы ++ уменьшал значения, но этого определенно не нужно делать! Будьте очень осторожны при неявном преобразовании ваших классов или структур в другие типы.