Кастомный оператор сравнения ==

266
21 ноября 2017, 21:09

Здравствуйте! В Unity3D реализована возможность опустить оператор сравнения когда объект проверяется на null, т.е. вместо if(instance != null) можно писать просто if(instance).

Т.е. получается type-to-bool.

https://docs.unity3d.com/ScriptReference/Object-operator_Object.html

Как такое реализовать для своих классов в C#?

Answer 1

Для начала предупреждение. Не стоит делать из C# C++. Если вы разрешите такие конструкции, вы получите «впридачу» и типичные ошибки языка C++. Например, присваивание внутри if внезапно начнёт компилироваться: if (a = b), и компилятор не будет находить за вас такие вот проблемы.

Кроме того, такой код неидиоматичен: код вида if (variable) для переменной, тип которой не bool, заставит ваших коллег удивлённо поднять брови.

Поэтому я бы советовал использовать такой код лишь в учебных/развлекательных целях.

Проще всего использовать неявное преобразование в bool:

class Test
{
    public static implicit operator bool(Test p) => p != null;
}

Имея это, вы сможете легко писать код в духе C++:

Test t1 = new Test(), t2 = null;
if (t1)
    Console.WriteLine("t1 != null");
if (!t2)
    Console.WriteLine("t2 == null");
if (t1 && t2)
    Console.WriteLine("t1 != null && t2 != null");
if (!t1 || !t2)
    Console.WriteLine("t1 == null || t2 == null");

Другой путь, более сложный — использовать операторы true и false.

Пример:

class Test
{
    public static bool operator true(Test p) => p != null;
    public static bool operator false(Test p) => p == null;
}

С этим можно писать проверки наподобие

Test t1 = new Test();
if (t1)
    Console.WriteLine("t1 != null");

Но !t1 уже не скомпилируется. Вам придётся писать оператор !. Чтобы работало && и ||, вам придётся определить и другие операторы:

class Test
{
    public static bool operator true(Test p) => p != null;
    public static bool operator false(Test p) => p == null;
    public static bool operator ! (Test p) => p == null;
    public static Test operator & (Test t1, Test t2) => t1 == null ? null : t2;
    public static Test operator | (Test t1, Test t2) => t1 != null ? t1 : t2;
    public static bool operator & (Test t1, bool t2) => t1 == null ? false : t2;
    public static bool operator | (Test t1, bool t2) => t1 != null ? true : t2;
}

Этот путь мне кажется более тяжёлым.

READ ALSO
Как определить цифру в числе

Как определить цифру в числе

Как определить цифру из введенного числа? Например, из числа 1337 узнать вторую цифру

530
Case C# укоротить

Case C# укоротить

Добрый день!

328
C# Перетаскивание формы за любой элемент. ( FormBorderStyle: None )

C# Перетаскивание формы за любой элемент. ( FormBorderStyle: None )

Здравствуйте, довольно давно использую несколько методов, приведу код нижеВозможно есть более гуманное решение этой задачи, поделитесь...

392
Программа не видит путь к файлу C:\Windows\ System32\nslookup.exe

Программа не видит путь к файлу C:\Windows\ System32\nslookup.exe

Программа не видит путь к файлу C:\Windows\System32\nslookupexe Проверка естественно всегда выдает "Путь не найден"

381