Что (если что) делает ++ в VB. NET? - PullRequest
2 голосов
/ 18 июня 2020

Я новичок в Visual Basi c (мой фон в основном C#), поэтому я только недавно обнаружил, что ++i - это не то же самое, что i+=1 в VB. NET. Однако мой код VB. NET по-прежнему компилируется, когда я передаю ++i в качестве параметра, даже если он не увеличивает переменную:

++i          'doesn't compile
i++          'doesn't compile
Foobar(i++)  'doesn't compile
Foobar(++i)  'compiles, but doesn't increment i

Тот факт, что последний оператор выше не ошибка заставляет меня задуматься, действительно ли ++ означает что-то в VB. NET, но не то, что я думал сначала. Если нет, то есть ли другая причина, по которой это не вызывает ошибку?

Ответы [ 2 ]

3 голосов
/ 18 июня 2020

Это просто унарная версия оператора + (см. docs ), примененная дважды.

Foobar(++i)
Foobar(+(+i))
Foobar(+(+(i)))
' These are all the same

Для числовых значений унарный + (т. Е. + без второго операнда) ничего не делает:

Если выражение2 отсутствует, оператор + является унарным оператором идентичности для неизмененного значения выражения.

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

Есть даже одно предложение, которое звучит так, как будто его можно применить, но оно не делает то, что он говорит, что если используется с унарным +:

Если выражение Object оценивается как Nothing или DBNull, оператор + обрабатывает его как String со значением of "".

Итак, вы ожидаете, что +Nothing также дает "", но вместо этого дает 0. Фактически, похоже, что унарный + преобразует нечисловые типы в Double, включая строки, для которых + иначе означало бы конкатенацию (например, +"1.234" дает 1.234, а +"Hello" дает ошибку что эта строка не может быть преобразована в Double - а с Option Strict On вы все равно не можете преобразовать никакую строку неявно). Кажется, что он больше похож на двоичный + с 0.0 в качестве первого операнда.

Вы также можете перегрузить унарный + отдельно от двоичного + и дать ему совершенно другое значение *. (Или сделайте наоборот - заставьте его ничего не делать даже для нечислового типа c, например, что делает TimeSpan - он снова возвращает исходный временной интервал, когда к нему применяется унарный +, а не Double.)

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

1 голос
/ 18 июня 2020

В VB нет оператора ++. Унарный оператор + аналогичен унарному оператору -, применяемому к числу. По умолчанию числа положительные, но так же, как вы можете явно сделать число отрицательным, добавив к нему префикс оператора -, вы можете сделать его явно положительным, добавив к нему префикс оператора +. Вы можете использовать столько операторов +, сколько захотите. Точно так же вы можете использовать столько операторов -, сколько захотите. Разница в том, что операторы + не изменяют значение, в отличие от операторов -.

В языках, основанных на C, присваивания фактически возвращают значение, в отличие от VB. В C# вы можете сделать это:

i += 1

, и он получит значение i, прибавит к нему 1, присвоит результат обратно i и затем вернет этот результат, поэтому вы можете использовать это выражение там, где ожидается значение. В VB он выполняет все те же действия вплоть до присвоения, но не возвращает значение, поэтому вы не можете использовать это выражение, где ожидается значение.

В языках на основе C, где вы размещаете оператор ++ имеет значение. Выражение:

++i

увеличивает i и возвращает окончательное значение, тогда как это выражение:

i++

увеличивает i и возвращает исходное значение. Вот почему некоторые утверждают, что язык C ++ на самом деле должен называться ++ C.

...