Добавить в цитаты Настройки чтения

Страница 60 из 188

И еще одно замечание: если перегружаются операторы == и !=, то для этого обычно требуется также переопределить методы Object.Equals() и Object.GetHashCode(). Эти методы и способы их переопределения подробнее рассматриваются в главе 11.Перегрузка операторов true и false

Ключевые слова true и false можно также использовать в качестве унарных операторов для целей перегрузки. Перегружаемые варианты этих операторов позволяютопределить назначение ключевых слов true и false специально для создаваемых классов. После перегрузки этих ключевых слов в качестве унарных операторов для конкретного класса появляется возможность использовать объекты этого класса для управленияоператорами if, while, for и do-while или же в условном выражении ?.

Операторы true и false должны перегружаться попарно, а не раздельно. Нижеприведена общая форма перегрузки этих унарных операторов.public static bool operator true(тип_параметра операнд){ // Возврат логического значения true или false.}public static bool operator false(тип_параметра операнд){ // Возврат логического значения true или false.}

Обратите внимание на то, что и в том и в другом случае возвращается результаттипа bool.

Ниже приведен пример программы, демонстрирующий реализацию операторовtrue и false в классе ThreeD. В каждом из этих операторов проверяется следующееусловие: если хотя бы одна из координат объекта типа ThreeD равна нулю, то этотобъект истинен, а если все три его координаты равны нулю, то такой объект ложен.В данном примере программы реализован также оператор декремента исключительнов целях демонстрации.// Перегрузить операторы true и false для класса ThreeD.using System;// Класс для хранения трехмерных координат.class ThreeD { int х, у, z; // трехмерные координаты public ThreeD() { х = у = z = 0; } public ThreeD(int i, int j, int k) { x = i; у = j; z = k; } // Перегрузить оператор true. public static bool operator true(ThreeD op) { if((op.x != 0) || (op.у != 0) || (op.z != 0)) return true; // хотя бы одна координата не равна нулю else return false; } // Перегрузить оператор false. public static bool operator false(ThreeD op) { if((op.x == 0) && (op.у == 0) && (op.z == 0)) return true; // все координаты равны нулю else return false; } // Перегрузить унарный оператор --. public static ThreeD operator --(ThreeD op) { ThreeD result = new ThreeD(); // Возвратить результат декрементирования. result.x = op.x - 1; result.у = op.у - 1; result.z = op.z - 1; return result; } // Вывести координаты X, Y, Z. public void Show() { Console.WriteLine(x + ", " + у + ", " + z); }}class TrueFalseDemo { static void Main() { ThreeD a = new ThreeD(5, 6, 7); ThreeD b = new ThreeD(10, 10, 10); ThreeD с = new ThreeD (0, 0, 0); Console.Write("Координаты точки a: "); a.Show(); Console.Write("Координаты точки b: "); b.Show(); Console.Write("Координаты точки с: "); c.Show(); Console.WriteLine(); if(a) Console.WriteLine("Точка а истинна."); else Console.WriteLine("Точка а ложна."); if(b) Console.WriteLine("Точка b истинна."); else Console.WriteLine("Точка b ложна."); if(с) Console.WriteLine("Точка с истинна."); else Console.WriteLine("Точка с ложна."); Console.WriteLine(); Console.WriteLine("Управление циклом с помощью объекта класса ThreeD."); do { b.Show(); b--; } while(b); }}

Выполнение этой программы приводит к следующему результату.Координаты точки а: 5, 6, 7Координаты точки b: 10, 10, 10Координаты точки с: 0, 0, 0Точка а истиннаТочка b истиннаТочка с ложнаУправление циклом с помощью объекта класса ThreeD.10, 10, 109, 9, 98, 8, 87, 7, 76, 6, 65, 5, 54, 4, 43, 3, 32, 2, 21, 1, 1

Обратите внимание на то, как объекты класса ThreeD используются для управления условным оператором if и оператором цикла do-while. Так, в операторах ifобъект типа ThreeD проверяется с помощью оператора true. Если результат этойпроверки оказывается истинным, то оператор if выполняется. А в операторе циклаdo-while объект b декрементируется на каждом шаге цикла. Следовательно, циклповторяется до тех пор, пока проверка объекта b дает истинный результат, т.е. этотобъект содержит хотя бы одну ненулевую координату. Если же окажется, что объектb содержит все нулевые координаты, его проверка с помощью оператора true дастложный результат и цикл завершится.Перегрузка логических операторов



Как вам должно быть уже известно, в C# предусмотрены следующие логическиеоператоры: &, |, !, && и ||. Из них перегрузке, безусловно, подлежат только операторы &, | и !. Тем не менее, соблюдая определенные правила, можно извлечь такжепользу из укороченных логических операторов && и ||. Все эти возможности рассматриваются ниже.Простой способ перегрузки логических операторов

Рассмотрим сначала простейший случай. Если не пользоваться укороченными логическими операторами, то перегрузку операторов & и | можно выполнять совершенно естественным путем, получая в каждом случае результат типа bool. Аналогичныйрезультат, как правило, дает и перегружаемый оператор !.

Ниже приведен пример программы, в которой демонстрируется перегрузка логических операторов !, & и | для объектов типа ThreeD. Как и в предыдущем примере,объект типа ThreeD считается истинным, если хотя бы одна из его координат не равнанулю. Если же все три координаты объекта равны нулю, то он считается ложным.// Простой способ перегрузки логических операторов// !, | и & для объектов класса ThreeD.using System;// Класс для хранения трехмерных координат.class ThreeD { int х, у, z; // трехмерные координаты public ThreeD() { х = у = z = 0; } public ThreeD(int i, int j, int k) { x = i; у = j; z = k; } // Перегрузить логический оператор |. public static bool operator |(ThreeD op1, ThreeD op2) { if( ((op1.x != 0) || (op1.у != 0) || (op1.z != 0)) | ((op2.x != 0) || (op2.у != 0) || (op2.z != 0)) ) return true; else return false; } // Перегрузить логический оператор &. public static bool operator &(ThreeD op1, ThreeD op2) { if( ((op1.x != 0) && (op1.у != 0) && (op1.z != 0)) & ((op2.x != 0) && (op2.y != 0) && (op2.z != 0)) ) return true; else return false; } // Перегрузить логический оператор !. public static bool operator !(ThreeD op) { if((op.x != 0) || (op.y != 0) || (op.z != 0)) return false; else return true; } // Вывести координаты X, Y, Z. public void Show() { Console.WriteLine(x + ", " + у + ", " + z); }}class TrueFalseDemo { static void Main() { ThreeD a = new ThreeD(5, 6, 7); ThreeD b = new ThreeD(10, 10, 10); ThreeD с = new ThreeD(0, 0, 0); Console.Write("Координаты точки a: "); a.Show(); Console.Write("Координаты точки b: "); b.Show(); Console.Write("Координаты точки с: "); c.Show(); Console.WriteLine(); if(!a) Console.WriteLine("Точка а ложна."); if(!b) Console.WriteLine("Точка b ложна."); if(!c) Console.WriteLine("Точка с ложна."); Console.WriteLine(); if(a & b) Console.WriteLine("a & b истинно."); else Console.WriteLine("a & b ложно."); if(a & c) Console.WriteLine("a & с истинно."); else Console.WriteLine("a & с ложно."); if(a | b) Console.WriteLine("a | b истинно."); else Console.WriteLine("a | b ложно."); if(a | c) Console.WriteLine("a | с истинно."); else Console.WriteLine("a | с ложно."); }}

При выполнении этой программы получается следующий результат.Координаты точки а: 5, 6, 7Координаты точки b: 10, 10, 10Координаты точки с: 0, 0, 0Точка с ложна.а & b истинно.a & с ложно.а | b истинно.а | с истинно.

При таком способе перегрузки логических операторов &, | и ! методы каждого изних возвращают результат типа bool. Это необходимо для того, чтобы использоватьрассматриваемые операторы обычным образом, т.е. в тех выражениях, где предполагается результат типа bool. Напомним, что для всех встроенных в C# типов данныхрезультатом логической операции должно быть значение типа bool. Поэтому вполне разумно предусмотреть возврат значения типа bool и в перегружаемых вариантах этих логических операторов. Но, к сожалению, такой способ перегрузки пригоденлишь в том случае, если не требуются укороченные логические операторы.Как сделать укороченные логические операторы доступными для применения