Перегрузка операторов отношения и операторов true - false

32

Перегрузка операторов отношения

Операторы отношения, например == и <, могут также перегружаться, причем очень просто. Как правило, перегруженный оператор отношения возвращает логическое значение true и false. Это вполне соответствует правилам обычного применения подобных операторов и дает возможность использовать их перегружаемые разновидности в условных выражениях. Если же возвращается результат другого типа, то тем самым сильно ограничивается применимость операторов отношения.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class MyArr
    {
        // Координаты точки в трехмерном пространстве
        public int x, y, z;

        public MyArr(int x = 0, int y = 0, int z = 0)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        // Перегружаем логический оператор ==
        public static bool operator ==(MyArr obj1, MyArr obj2)
        {
            if ((obj1.x == obj2.x) && (obj1.y == obj2.y) && (obj1.z == obj2.z))
                return true;
            return false;
        }

        // Теперь обязательно нужно перегрузить логический оператор !=
        public static bool operator !=(MyArr obj1, MyArr obj2)
        {
            if ((obj1.x != obj2.x) || (obj1.y != obj2.y) || (obj1.z != obj2.z))
                return true;
            return false;
        }
        
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyArr myObject1 = new MyArr(x: 4, z: 5, y: 12);
            MyArr myObject2 = new MyArr(x: 4, z: 5, y: 12);

            if (myObject1 == myObject2)
                Console.WriteLine("Объекты равны");

            Console.ReadLine();
        }
    }
}

Обратите внимание, что на перегрузку операторов отношения накладывается следующее важное ограничение: они должны перегружаться попарно. Так, если перегружается оператор <, то следует перегрузить и оператор >, и наоборот. Ниже приведены составленные в пары перегружаемые операторы отношения:

!=   ==	
<    >
<=   >=

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

Перегрузка операторов 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:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class MyArr
    {
        // Координаты точки в трехмерном пространстве
        public int x, y, z;

        public MyArr(int x = 0, int y = 0, int z = 0)
        {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        // Перегружаем логический оператор ==
        public static bool operator ==(MyArr obj1, MyArr obj2)
        {
            if ((obj1.x == obj2.x) && (obj1.y == obj2.y) && (obj1.z == obj2.z))
                return true;
            return false;
        }

        // Теперь обязательно нужно перегрузить логический оператор !=
        public static bool operator !=(MyArr obj1, MyArr obj2)
        {
            if ((obj1.x != obj2.x) || (obj1.y != obj2.y) || (obj1.z != obj2.z))
                return false;
            return true;
        }

        // Перегружаем оператор false
        public static bool operator false(MyArr obj)
        {
            if ((obj.x <= 0) || (obj.y <= 0) || (obj.z <= 0))
                return true;
            return false;
        }

        // Обязательно перегружаем оператор true
        public static bool operator true(MyArr obj)
        {
            if ((obj.x > 0) && (obj.y > 0) && (obj.z > 0))
                return true;
            return false;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyArr myObject1 = new MyArr(x: 4, z: 5, y: 12);
            MyArr myObject2 = new MyArr(x: 4, z: 5, y: 12);

            if (myObject1 == myObject2)
                Console.WriteLine("Объекты равны");

            if (myObject1)
                Console.WriteLine("Все координаты объекта myObject1 положительны");

            Console.ReadLine();
        }
    }
}
Пройди тесты
Лучший чат для C# программистов