Вопрос

В C есть два странных оператора#:

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

Допустим, у меня есть следующий класс:

    public class MyType
    {
        public readonly int Value;

        public MyType(int value)
        {
            Value = value;
        }

        public static bool operator true (MyType mt)
        {
            return  mt.Value > 0;
        }

        public static bool operator false (MyType mt)
        {
            return  mt.Value < 0;
        }

    }

Итак, я могу написать следующий код:

    MyType mTrue = new MyType(100);
    MyType mFalse = new MyType(-100);
    MyType mDontKnow = new MyType(0);

    if (mTrue)
    {
         // Do something.
    }

    while (mFalse)
    {
        // Do something else.
    }

    do
    {
        // Another code comes here.
    } while (mDontKnow)

Однако для всех приведенных выше примеров выполняется только оператор true.Итак, для чего хорош оператор false в C #?

Примечание:Можно найти и другие примеры здесь, здесь и здесь.

Это было полезно?

Решение

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

Тот Самый && и || операторы не могут быть переопределены, но если вы переопределите |, &, true и false именно таким образом компилятор вызовет | и & когда ты пишешь || и &&.

Например, посмотрите на этот код (из http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading - где я узнал об этом трюке; архивированная версия автор: @BiggsTRC):

public static AbstractCriterion operator &(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new AndExpression(lhs, rhs);
}

public static AbstractCriterion operator |(AbstractCriterion lhs, AbstractCriterion rhs)
{
       return new OrExpression(lhs, rhs);
}

public static bool operator false(AbstractCriterion criteria)
{
       return false;
}
public static bool operator true(AbstractCriterion criteria)
{
       return false;
}

Очевидно, что это побочный эффект и не тот способ его использования, которым он предназначен, но он полезен.

Другие советы

Сег9 и Nir:спасибо за ваши ответы.Эти ответы указали мне на Статья Стива Айхерта и это указало мне на msdn:

Операция x && y оценивается как T.false(x) ?x :T.&(x, y), где T.false(x) - это вызов оператора false, объявленного в T, а T.&(x, y) - это вызов выбранного оператора &.Другими словами, сначала вычисляется x, и для результата вызывается оператор false, чтобы определить, является ли x определенно false .Затем, если x определенно равно false, результатом операции будет значение, ранее вычисленное для x.В противном случае вычисляется y, и выбранный оператор & вызывается для значения, ранее вычисленного для x, и значения, вычисленного для y, для получения результата операции.

Страница, на которую вы ссылаетесь http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx говорит, для чего они были предназначены, что было способом обработки nullable bools до того, как были введены типы значений с nullable.

Я бы предположил, что в настоящее время они хороши для тех же целей, что и ArrayList, т. е.абсолютно ничего.

AFAIK, это было бы использовано в тесте на ложь, например, когда && в игру вступает оператор.Помните, && короткое замыкание, поэтому в выражении

if ( mFalse && mTrue) 
{
   // ... something
}

mFalse.false() вызывается, и по возвращении true выражение сводится к вызову 'mFalse.true()' (который затем должен возвращать false, или все станет странным).

Обратите внимание, что вы должны реализовать & оператор для того, чтобы это выражение скомпилировалось, поскольку оно используется, если mFalse.false() ВОЗВРАТ false.

Как следует из статьи MSDN, на которую вы ссылались, она была предоставлена для того, чтобы разрешить использование логических типов с нулевым значением до Nullable (т. Е.int?, bool? и т.д.) тип, введенный в язык в C # 2.Таким образом, вы бы сохранили внутреннее значение, указывающее, является ли это значение true, false или null, т.е.в вашем примере >0 для true, <0 для false и ==0 для null, и тогда вы получите нулевую семантику в стиле SQL.Вам также пришлось бы реализовать метод или свойство .IsNull для того, чтобы недействительность могла быть проверена явно.

Для сравнения с SQL представьте таблицу Table с 3 строками, для значения Foo установлено значение true, 3 строками, для значения Foo установлено значение false, и 3 строками, для значения Foo установлено значение null.

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE
6

Чтобы подсчитать все строки, вам нужно будет выполнить следующее:-

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE OR Foo IS NULL
9

Этот синтаксис 'IS NULL' будет иметь эквивалентный код в вашем классе как .IsNull() .

LINQ делает сравнение с C # еще более понятным:-

int totalCount = (from s in MyTypeEnumerable
                 where s || !s
                 select s).Count();

Представив, что MyTypeEnumberable имеет точно такое же содержимое базы данных, т.е.3 значения равны true, 3 значения равны false и 3 значения равны null.В этом случае totalCount в данном случае будет равен 6.Однако, если мы перепишем код следующим образом:-

int totalCount = (from s in MyTypeEnumerable
                 where s || !s || s.IsNull()
                 select s).Count();

Тогда totalCount будет равен 9.

Пример DBNull, приведенный в связанной статье MSDN об операторе false, демонстрирует класс в BCL, который имеет именно такое поведение.

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

Обновить: Я только что заметил, что вам нужно вручную переопределить логические операторы !, || и &&, чтобы это работало должным образом.Я полагаю, что оператор false вводится в эти логические операторы, т.е.указывающий на истинность, ложность или "иное".Как отмечено в другом комментарии!x не сработает с места в карьер;вы должны перегружаться!.Странность!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top