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

Значения С# правды и ложности

В JavaScript есть идея правды и фальшивых значений.

например.

  • 0: Всегда false
  • 1: Всегда верно
  • '0': Всегда верно
  • '1': Всегда верно

Существует ли эквивалентный список правдоподобных и ложных значений на языке С# на платформе .NET?

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

if(obj != null)
{
   // Do something with the object
}

Когда я могу написать следующее

if(obj)
{
   // Do something with the object
}
4b9b3361

Ответ 1

С# имеет только литеральные значения true и false.

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

Важно отметить, что "сильная типизация" не является причиной того, что С# не подразумевает конвертацию в значения "правдивость/фальшивость". Язык намеренно пытается избежать ловушек других скомпилированных языков, таких как С++, где определенные значения могут быть правдивыми, например "0" или "1", что может позволить вам сделать синтаксическую ошибку, которую вы могли бы не заметить до времени выполнения ваш код ведет себя неожиданно.

Ответ 2

По умолчанию С# предоставляет только true и false.

Тем не менее, вы можете иметь свои собственные пользовательские типы, которые становятся "правдивыми" и "ложными", реализуя оператор true. Когда тип реализует оператор true, экземпляры этого типа могут использоваться как булево выражение. Из раздела 7.19 Спецификация языка С#:

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

Тип структуры DBBool в §11.4.2 предоставляет пример типа, который реализует оператор true и оператор false.

Вот фрагмент кода объявления оператора true (который, вероятно, выполнит то, что вы хотели сделать в своем вопросе):

public static bool operator true(MyType myInstance)
{
    return myInstance != null;
}

Если вы реализуете оператор true, то вы также должны реализовать оператор false.

Ответ 3

Правильный ответ на ваш вопрос содержится в разделе 7.19 спецификации С# 3.0, которую вы можете легко найти в Интернете. Для вашего удобства соответствующий текст:

7.19 Булевы выражения

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

Управляющее условное выражение оператора if [...] является логическое выражение. [...]

Булево выражение должно быть типа, который может быть неявным преобразован в bool или типа, который реализует оператор true. Если ни требование выполняется, ошибка времени компиляции.

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

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

Ответ 4

Короткий ответ:

В С#:

  • true: Всегда true
  • false: всегда false

Все остальное не является логическим значением.

Ответ 5

Код, подобный этому, будет (и должен) не скомпилироваться. Если вы специально хотите переопределить это поведение, вы можете создать неявное преобразование в boolean. Что-то вроде этого:

public class Foo {
    public static implicit operator bool(Foo me) {
        if (me == null) {
            return false;
        }

        return true; // maybe add more logic before saying True
    }
}

Я бы назвал это плохой практикой, потому что кодер, не знакомый с вашим проектом, не сразу понял, какая логика кормит логическое преобразование. Более идиоматический способ сделать это будет заключаться в том, чтобы явно рассказать читателю, что делает ваш код, например, встроенный класс String, со статической вспомогательной функцией:

if (String.IsNullOrEmpty(str){
    // ...
}

Код записывается только один раз и часто читается; оптимизируйте для удобочитаемости.

Ответ 6

Оператор if оценивает то, что может быть преобразовано в /equates в/returns boolean или в boolean... проверка на null, как obj!= null, является одним из таких выражений,

'if (obj)' может работать, если только если obj может преобразовать в bool, а не если он равен null.

Ответ 7

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

public static bool IsTruthy(this object obj)
{
    if (obj == null || obj is DBNull)
        return false;

    var str = obj as string;
    if (str != null)
        return !string.IsNullOrWhiteSpace(str) && 
            !str.Trim().Equals(bool.FalseString, StringComparison.OrdinalIgnoreCase);

    try
    {
        if (Convert.ToDecimal(obj) == 0)
            return false;
    }
    catch { }

    if (obj is BigInteger)
        return ((BigInteger)obj) != 0; 

    return true;
}

Некоторые примечания об этом:

  • Этот метод несовместим с тем, как javascript обрабатывает строку "False"
  • Этот метод возвращает true для пустых перечислений, что согласуется с javascript

Ответ 8

Если obj - это тип, который вы создали, вы можете определить неявное преобразование пользователя в bool.

Ответ 9

Вы можете определить свою правду и ложь с помощью методов расширения.

public static bool Falsy(this object obj) {
        if(obj == null) return true;
        if (obj is string)
            if(obj as string == string.Empty) return true;
        if(obj is byte)
            if((byte)obj == 0) return true;
        if(obj is sbyte)
            if((sbyte)obj == 0) return true;
        if(obj is short)
            if((short)obj == 0) return true;
        if(obj is ushort)
            if((ushort)obj == 0) return true;
        if(obj is int)            
            if((int)obj == 0) return true;
        if(obj is uint)
            if((uint)obj == 0) return true;
        if(obj is long)
            if((long)obj == 0) return true;
        if(obj is ulong)
            if((ulong)obj == 0) return true;
        if(obj is float)
            if((float)obj == 0) return true;
        if(obj is double)
            if((double)obj == 0) return true;
        if(obj is decimal)
            if((decimal)obj == 0) return true;
        if(obj is IEnumerable<object>)
            if((obj as IEnumerable<object>).Count<object>() == 0)
                return true;
        if(obj is Array)
            if(((Array)obj).Length <= 0)
                return true;
        if(obj is ObjectId)
            if(((ObjectId)obj).Pid == 0) return true;
        if(obj is System.Collections.ObjectModel.ObservableCollection<M>)
            if(((ObservableCollection<M>)obj).Count <= 0) return true;
                return false;
}

public static bool Truthy(this object obj) {
   return !Falsy(obj);
}

Итак, вы можете сделать что-то вроде:

if (customerList.Falsy()) {throw new Exception ( "Не может быть пустым или пустым" ); }

Ответ 10

С# - это статически типизированный язык, то есть тип объектов имеет значение при настройке того, что это такое.

Например, "4" != 4.

JavaScript, однако, является динамически типизированным языком, поэтому типы имеют мало значения.

Итак, в JavaScript "4" == 4.

"Истинные" значения - это значения, которые просто удовлетворяют x == true, а значения "falsey" - нет.

Без безопасности типа некоторые функции, такие как перегрузка, будут давать непредсказуемое поведение.

Для получения дополнительной информации вы можете увидеть здесь.