Перегрузка операций
C# позволяет переопределить действие большинства операций так, чтобы при использовании с объектами конкретного класса они выполняли заданные функции. Это дает возможность применять экземпляры собственных типов данных в составе выражений таким же образом, как стандартных, например:
MyProject a, b, с;
с = а + b; // используется операция сложения для класса MyProject;
Определение собственных операций класса часто называют перегрузкой операций. Перегрузка обычно применяется для классов, описывающих математические или физические понятия, то есть таких классов, для которых семантика операций делает программу более понятной. Если назначение операции интуитивно не понятно с первого взгляда, перегружать такую операцию не рекомендуется.
Операции класса описываются с помощью методов специального вида (функций-операций). Перегрузка операций похожа на перегрузку обычных методов.
Синтаксис операции:
[ атрибуты ] спецификаторы объявитель_операции тело
|
|
В качестве спецификаторов одновременно используются ключевые слова public и static. Кроме того, операцию можно объявить как внешнюю (extern).
Объявитель операции содержит ключевое слово operator, по которому и опознается описание операции в классе. Тело операции определяет действия, которые выполняются при использовании операции в выражении. Тело представляет собой блок, аналогичный телу других методов.
Новые обозначения для собственных операций вводить нельзя. Для операций класса сохраняются количество аргументов, приоритеты операций и правила ассоциации (справа налево или слева направо), используемые в стандартных типах данных.
При описании операций необходимо соблюдать следующие правила:
- операция должна быть описана как открытый статический метод класса (спецификаторы public static);
- параметры в операцию должны передаваться по значению (то есть не должны предваряться ключевыми словами ref или out);
- сигнатуры всех операций класса должны различаться;
- типы, используемые в операции, должны иметь не меньшие права доступа, чем сама операция (то есть должны быть доступны при использовании операции)
Можно определять в классе следующие унарные операции:
+ -! - ++ -- true false
Синтаксис объявителя унарной операции: тип operator унарная_операция
(параметр) Примеры заголовков унарных операций:
public static int operator +(MyProject m)
public static MyProject operator --(MyProject m)
public static bool operator true(MyProject m)
Параметр, передаваемый в операцию, должен иметь тип класса, для которого она определяется. Операция должна возвращать:
- для операций +, -,! и -величину любого типа;
- для операций ++ и - - величину типа класса, для которого она определяется;
|
|
- для операций true и false величину типа bool.
Операции не должны изменять значение передаваемого им операнда. Операция, возвращающая величину типа класса, для которого она определяется, должна создать новый объект этого класса, выполнить с ним необходимые действия и передать его в качестве результата.
В качестве примера рассмотрим перегрузку унарной операций в классе вектор:
class Vector
{
public static Vector operator -(Vector a) // перегрузка унарного минуса
{
Vector b = new Vector(-a.X, -a.Y);
return b;
}
}
Данная перегрузка позволит вычислить обратный вектор:
Vector Z = - Vector a;