Подтвердить что ты не робот

Зачем перегружать true и false вместо определения оператора bool?

Я читал о перегрузке true и false на С#, и я думаю, что понимаю основную разницу между этим и определяя оператор bool. Пример, который я вижу вокруг, выглядит примерно так:

public static bool operator true(Foo foo) {
  return (foo.PropA > 0);
}
public static bool operator false(Foo foo) {
  return (foo.PropA <= 0);
}

Для меня это то же самое, что сказать:

public static implicit operator bool(Foo foo) {
  return (foo.PropA > 0);
}

Различие, насколько я могу судить, заключается в том, что, определяя true и false отдельно, вы можете иметь объект, который является как истинным, так и ложным, или ни истинным, ни ложным:

public static bool operator true(Foo foo) { return true; }
public static bool operator false(Foo foo) { return true; }
//or
public static bool operator true(Foo foo) { return false; }
public static bool operator false(Foo foo) { return false; }

Я уверен, что есть причина, по которой это разрешено, но я просто не могу придумать, что это такое. Для меня, если вы хотите, чтобы объект мог быть преобразован в true или false, один оператор bool имеет наибольший смысл.

Может ли кто-нибудь дать мне сценарий, когда имеет смысл сделать это другим путем?

Спасибо

4b9b3361

Ответ 1

Как docs говорят, что перегрузка true и false предназначена для поддержки (нулевых) типов баз данных (Да/Нет, Y/N, 0/1 и т.д.).

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

Ответ 2

Я понятия не имел, что эти операторы существуют. Это означает, что вы можете реализовать парадокс самоотрицания:

public class ThisClassIsFalse
{
    public static bool operator true(ThisClassIsFalse statement)
    {
        return statement ? false : true;
    }

    public static bool operator false(ThisClassIsFalse statement)
    {
        return statement ? true : false;
    }
}

Итак, теперь мы знаем истинное решение этого классического парадокса... StackOverflowException.

Ответ 3

В зависимости от системы истинным может быть любое ненулевое значение. В других случаях это может быть любое положительное значение.

Другие системы не являются действительно логическими и позволяют третьему состоянию null или nill для логических значений, поэтому вы можете перегрузить true и false, а также перегрузить один оператор bool.

Ответ 4

Я видел, как люди перегружали перегрузки true и false, чтобы делать умные вещи, такие как создание выражений в .NET 2.0, до того, как Linq существовал.

Ayende разработал такой синтаксис, чтобы строить критерии запросов NHibernate, используя его проект NHQG:

return Repository.FindAll(
    (Where.Publisher.Name == name) &&
    (Where.Publisher.City == city));