Какой тип должен иметь перегрузка оператора отрицания (!)? - PullRequest
4 голосов
/ 22 июня 2011

Если я перегружаю оператор ! в классе, какой тип он должен возвращать? В книге я нашел это (частичное перечисление):

public class MyType {
    public int IntField { get; set; }

    public MyType(int intField) {
        IntField = intField;
    }

    public static bool operator !(MyType mt) {
        return (mt.IntField <= 0);
}

Он компилируется, но я ожидаю, что оператор ! вернет экземпляр MyType, что-то вроде

public static MyType operator !(MyType mt) {
    var result = new MyType(-mt.IntField);
    return result;
}

На самом деле, я ожидаю, что компилятор потребует, чтобы оператор ! вернул MyType. Но это не так.

Итак ... почему возвращаемый тип оператора ! не должен быть содержащим типом? Вы do должны сделать тип возвращаемого значения ++ или -- типом вмещения.

1 Ответ

11 голосов
/ 22 июня 2011

Предположим, я спросил вас "что такое возвращаемый тип конкатенации"?Что бы вы сказали?Вероятно, вы бы обернулись и спросили "конкатенация чего?"Конкатенация определяется в символах, строках, последовательностях, каталитических запросах, языках, дискретных конечных автоматах и ​​тысячах других вещей, поэтому возвращаемый тип определяется типом аргументов.Но обычно тип конкатенации является типом аргументов.Не всегда;например, конкатенация двух символов представляет собой строку.Но обычно.

Точно так же вопрос "каков тип оператора!?"полностью зависит от того, что отрицается, и вы не сказали, что отрицаете.Обычно отрицание Т - это еще один Т, но это не обязательно.

Я подозреваю, что вы не задаете правильный вопрос.Я думаю, что вопрос, который вы должны задать, это «каков реалистичный сценарий, в котором вы бы перегружали оператор!»?Пример, который вы привели из книги, ужасен;это не мотивирует, почему автор кода вообще переопределяет оператор.

Вот более реалистичный пример.Предположим, мы жили в мире без обнуляемых типов.Вы можете решить использовать трехзначную логику:

sealed class MyBool
{
    private MyBool() {} // No one creates it!
    public static MyBool True = new MyBool();
    public static MyBool False = new MyBool();
    public static MyBool Unknown = new MyBool();

Хорошо, каково правило для отрицания MyBool?True становится False, False становится True, Unknown остается неизвестным:

    public static MyBool operator !(MyBool b)
    { 
        if (b == True) return False;
        if (b == False) return True;
        return Unknown;
    }

В этом сценарии тип!оператор MyBool.

Конечно, начиная с C # 2.0 у нас есть трехзначная логика в форме Nullable<bool>, но вам может потребоваться более сложная логика (или вы можете писать код на C # 1.0).

Труднее придумать разумные примеры ситуаций, в которых отрицание Foo приводит к бару;Возможна ситуация с «монадными» объектами рабочего процесса, когда отрицание объекта данного типа - это объект другого типа, представляющий отложенное выполнение отрицания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...