Зачем использовать одну переменную в качестве условной оценки?

В моем понимании условных выражений во всем программировании, будь то оператор if, цикл while и т. Д., Конкретное утверждение проверяется как истинное или ложное.

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

someType aVariable = someValue;

If (aVariable) 
{
 //do this
}

Что будет оцениваться как истинное или ложное в этом случае? Очевидно, что если aVariable представляет логическое значение, это было бы просто, но обычно явное значение вообще не является логическим и часто содержит NULL. Еще раз, я вижу это почти на каждом языке, на который я смотрел, поэтому я предполагаю, что это не зависит от языка.

РЕДАКТИРОВАТЬ 1: поскольку мне сообщили, что это может зависеть от языка, я добавлю, что я очень часто вижу это в C#, и рассматриваемая переменная может быть либо ссылочным типом, либо тип значения.

EDIT 2: все очень хорошие ответы, которые я резюмировал ниже:

(a) зависит от языка, может ли конкретная переменная, отличная от логической, быть оценена как логическая (b) во многих случаях, если язык поддерживает такую ​​оценку, любая ненулевая, непустая или ненулевая value обычно оценивается как TRUE (целые числа C/C++) (c) для языков, которые не поддерживают такое неявное вычисление, в определение класса необходимо добавить приведение к bool, например (C#)


person Snik    schedule 17.06.2014    source источник
comment
Я уверен, что нюансы зависят от языка. В php этот оператор if будет оцениваться как true, если: aVariable содержит логическое значение true, строку любой длины, массив с любыми непустыми элементами, объект с любыми непустыми элементами или число, отличное от нуля. Если aVariable содержит false, строку без длины, число 0, пустой массив, пустой объект или null, оператор if будет оцениваться как false. Это также верно в javascript.   -  person random_user_name    schedule 18.06.2014
comment
Вы не можете сделать это в C#, если только aVariable не является bool или не имеет неявного преобразования в bool.   -  person Lee    schedule 18.06.2014
comment
Ли - я не могу поручиться за достоверность этого примера, но вот ссылка на него, по крайней мере, на C #. См. код внизу: answers.unity3d.com/questions/439308/   -  person Snik    schedule 18.06.2014
comment
@StevenNikolic - Да, похоже, они предоставили неявное преобразование в bool в своем базовом классе Object. Я добавил ответ.   -  person Lee    schedule 18.06.2014


Ответы (4)


Как указывалось в других ответах, детали зависят от языка. В C# вы можете сделать это, только если aVariable является bool или имеет неявное преобразование в bool (или реализует операторы true и false).

В вашей ссылке Unity кажется, что их базовый тип Object имеет неявное преобразование в bool, которое возвращает, является ли объект нулевым, например.

public class Object
{
    public static implicit operator bool(Object b) { return b != null; }
}
person Lee    schedule 17.06.2014

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

// groovy code
if(someVariable) {
    // do something
}

В этом коде someVariable может быть чем угодно, и это действительно Groovy. Правило состоит в том, что есть определенные вещи, которые оцениваются как false, и к ним относятся логическое значение false, число ноль, пустая коллекция, пустая строка и нуль. Все остальное верно. Это еще не все, но копаться в этом будет куча специфических вещей Groovy, и я просто иллюстрирую пример.

Не все языки программирования имеют такое поведение. Разработчик языка должен решить, как все это работает.

person Jeff Scott Brown    schedule 17.06.2014

Это работает только в C#, если aVariable либо уже является логическим значением, либо неявно приводится к логическому значению.

В других языках, особенно в C и C++, в этом контексте могут использоваться целые числа. Если они равны 0, то false. В противном случае true.

Указатели работают точно так же - поскольку NULL (в основном) равен 0, делаем что-то вроде

float *ptr = null_ptr;

if(ptr)
{
/// will not be executed
}

И так далее.

person 3Dave    schedule 17.06.2014
comment
Спасибо за ваш ответ, Дэвид, как упоминалось в моем комментарии выше Ли, будет ли этот пример неявно приведен к bool, и если да, то как мне это определить - http:/answers.unity3d.com/questions/439308/create-fading -sprite-in-c.html - person Snik; 18.06.2014

Во многих языках значение переменных, отличных от логического типа, может оцениваться как истинное или ложное условие. Например, в C/C++ значения, которые оцениваются как 0, такие как int, содержащий 0, или нулевой указатель, оцениваются как false. Все остальные значения оцениваются как истинные. Например, значение int:

int foo = 5;
if (foo)
{
    // This code gets run
}

В других языках, таких как C# и Java, такое поведение запрещено — приведенный выше код вызовет ошибку компиляции, так как вы должны предоставить логическое выражение в качестве условного оператора (эквивалентом в данном случае является foo != 0).

Для этого есть веские причины. Незначительные ошибки могут быть введены, если разрешить оценку значения, отличного от логического значения, в качестве условия. Например, в приведенном выше if инженер, возможно, намеревался написать foo >= 0, но отвлекся, прежде чем закончил. В C# ошибка компиляции привлекла бы их внимание к ошибке. В C/C++ тело if будет выполняться, если foo меньше или больше 0. Ошибка компилятора не генерируется, так как это допустимый код, и возникает ошибка.

person Chris Mantle    schedule 17.06.2014
comment
Я должен спросить: отвлеклись, прежде чем они закончили? - person 3Dave; 22.07.2014
comment
Нет, это был мой ответ. Я ответил до того, как на вопрос были внесены правки, которые сузили его объем. Первоначально казалось, что это общий вопрос о том, как типы данных, отличные от bool, могут использоваться в качестве условных выражений (и не указывалось C#). Когда его отредактировали, стало ясно, что ОП действительно спрашивал о неявном преобразовании в С#. Ну, ответ Ли сортирует это. Я не хотел редактировать свой ответ, чтобы включить избыточную информацию, но мне не хотелось его удалять, поскольку он все еще имел некоторую ценность. - person Chris Mantle; 22.07.2014