Шаг 113.
Язык программирования C#. Начала
Перегрузка операторов. Перегрузка операторов true и false

    На этом шаге мы рассмотрим особенности перегрузки этих операторов.

    Операторы true и false являются унарными и перегружаются в паре (соответствующие операторные методы называются operator true и operator false). Оба оператора результатом возвращают значение логического типа.

    Объекты можно проверять на предмет "истинности" или "ложности". При проверке объекта на "истинность" вызывается операторный метод для оператора true. Если операторный метод возвращает значение true, то такой объект является "истинным". Если операторный метод возвращает значение false, то объект не считается "истинным".

    При проверке объекта на "ложность" вызывается операторный метод для оператора false. Если операторный метод возвращает значение true, то объект считается "ложным". Если операторный метод возвращает значение false, то объект не считается "ложным".

    Строго говоря, если объект не является "истинным", то это не означает, что он "ложный". Из того, что объект не является "ложным", не следует, что объект "истинный". Проверка объекта на "истинность" и "ложность" выполняется в разных ситуациях, которые обсуждаются далее.

    Это особые операторы в том смысле, что не сразу понятно, когда и как они применяются. Вместе с тем ситуация не такая уж и сложная. Операторный метод для оператора true вызывается в тех случаях, когда объект указан условием - например, в условном операторе или операторе цикла. Также операторный метод для оператора true вызывается при проверке первого операнда в выражении на основе оператора || (сокращенная форма оператора "логическое или"). Операторный метод для оператора false вызывается при проверке первого операнда в выражении, на основе оператора && (сокращенная форма оператора "логическое и").


Специфику перегрузки операторов true и false при работе с операторами || и && мы обсудим немного позже.

    Небольшой пример, иллюстрирующий перегрузку операторов true и false, представлен в примере ниже.

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

namespace pr113_1
{
    // Класс с перегрузкой операторов true и false: 
    class MyClass {
        // Целочисленное поле: 
        public int code;
        // Конструктор с одним аргументом: 
        public MyClass(int n) {
            // Значение поля: 
            code = n;
        }

        // Перегрузка оператора true:
        public static bool operator true(MyClass obj) {
            // Проверяется значение поля объекта: 
            if ( obj.code >= 5) 
                return true; 
            else return false;
        }

        // Перегрузка оператора false:
        public static bool operator false(MyClass obj) {
            // Используется операторный метод для оператора true.
            // Объект использован как условие: 
            if(obj) return false; 
            else return true; 
        }
    }

    // Класс с главным методом: 
    class Program
    {
        // Главный метод:
        static void Main()
        {
            // Создание объекта класса:
            MyClass obj = new MyClass(10);
            // Использование операторного метода для 
            // оператора true. Объект использован как условие: 
            while(obj) {
                // Отображение значения поля объекта:
                Console.Write(obj.code + " ");
                // Уменьшение значения поля объекта: 
                obj.code--;
            }
            Console.WriteLine();
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

    Ниже представлен результат выполнения программы.


Рис.1. Результат выполнения программы

    Мы в классе MyClass с целочисленным полем code и конструктором (с одним аргументом) описываем еще два операторных метода, которые называются operator true и operator false. Оба операторных метода описаны с одним аргументом (обозначен как obj), являющимся объектом класса MyClass. Результатом методами возвращается значение типа bool. В методе operator true() результат вычисляется так: в условном операторе проверяется условие obj.code>=5, состоящее в том, что значение поля code объекта-операнда больше или равно 5. Если так, то результатом метода возвращается значение true. В противном случае метод возвращает значение false.


Получается так, что если у объекта значение целочисленного поля больше или равно 5, то при проверке на "истинность" этот объект признается "истинным". Если значение поля меньше 5, то при проверке на истинность объект "истинным" не признается.

    Описание метода operator false () тоже базируется на использовании условного оператора. Но на этот раз условием в условном операторе указан объект obj (аргумент метода). Если объект указан в качестве условия, то проверка условия сводится к проверке объекта на "истинность": если объект признается "истинным", то это интерпретируется как истинность условия, а если объект истинным не признается, то условие будет интерпретироваться как ложное. Проще говоря, объект obj в условии в условном операторе означает, что для этого объекта будет вызван операторный метод operator true (). Результат, возвращаемый методом, дает значение условия в условном операторе. Если объект obj истинный, то результатом метода operator false() возвращается значение false. Если объект не является истинным, то результатом метода operator false() возвращается значение true.


Мы определили методы operator true() и operator false() так, что если один метод возвращает значение true, то другой возвращает значение false, и наоборот. Получается, что если объект не "истинный", то он "ложный", а если объект не "ложный", то он "истинный". Но в общем случае все могло бы быть иначе.

    В главном методе программы создается объект obj класса MyClass, и целочисленное иоле этого объекта получает значение 10. После этого выполняется цикл while, в котором условием указан объект obj. Каждый раз при проверке условия для объекта obj вызывается операторный метод operator true(). Пока значение поля объекта больше или равно 5, объект интерпретируется как "истинный" и условие в циклической конструкции тоже истинно. За каждую итерацию цикла командой

  Console.Write(obj.code + " ");
текущее значение поля code объекта obj отображается в консольном окне, после чего командой
  obj.code--;
значение поля уменьшается на единицу. В результате в консольном окне появляется последовательность числовых значений от 10 до 5 включительно.

    На следующем шаге мы рассмотрим перегрузку логических операторов.




Предыдущий шаг Содержание Следующий шаг