‹› И не в VB.NET

У меня есть захватывающая задача узнать об операторах VB.NET <> и Not. Not - я предполагаю, что по своему небольшому использованию - это функциональный эквивалент ! в таких языках, как C #, а <> эквивалентен !=.

Похоже, что в VB.NET распространенной проблемой является выполнение логических выражений для объектов, на которые нет ссылки. Итак, если мы сделаем

If Request.QueryString("MyQueryString") <> Nothing Then

На самом деле это не удастся, если строка запроса не существует. Почему, я не знаю. То, как это делается старшими кодерами, выглядит следующим образом:

If Not Request.QueryString("MyQueryString") Is Nothing Then

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

Я спрашиваю об этом, так как мне нужно написать документацию по стандартам, и мы определяем использование либо Not, либо <>. Любые идеи о том, как это должно быть, или вам должно это сделать?


person Kezzer    schedule 16.03.2009    source источник


Ответы (9)


Я всегда использовал следующее:

If Request.QueryString("MyQueryString") IsNot Nothing Then

Но только потому, что синтаксически он читается лучше.

При тестировании действительной записи QueryString я также использую следующее:

If Not String.IsNullOrEmpty(Request.QueryString("MyQueryString")) Then

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

person Charlie    schedule 16.03.2009
comment
Итак, просто для уточнения, в чем разница между этими двумя? Я предполагаю, что IsNot Nothing проверяет нулевую ссылку, но последний пример также проверяет пустоту или нулевое значение value, а не ссылку? - person Kezzer; 16.03.2009
comment
Отличный ответ, @Charles. Почти так же, как я бы написал. +1 - person Cerebrus; 16.03.2009
comment
Кеззер - верхний просто проверяет незаполненную переменную, например. ноль/ничего. Он не обнаружит пустую строку, я думаю, что второй является более полным оператором и выполняет больше работы для вас. - person Charlie; 16.03.2009

Is не совпадает с = -- Is сравнивает ссылки, а = сравнивает значения.

Если вы используете версию 2 .Net Framework (или более позднюю), есть оператор IsNot, который будет делать правильные вещи и будет читаться более естественно.

person Rowland Shaw    schedule 16.03.2009
comment
О, дерьмо, это научит меня предполагать семантику равенства - это означает, что я только что поменял одну ошибку на другую в проекте на работе. Я хотел бы использовать контроль версий... - person ; 26.04.2012

Я думаю, что ваш вопрос сводится к «разнице между (Is и =), а также (IsNot и ‹>)».

Ответ в обоих случаях один:

= и <> неявно определены для типов значений, и вы можете явно определить их для своих типов.

Is и IsNot предназначены для сравнения между типами ссылок, чтобы проверить, относятся ли две ссылки к одному и тому же объекту.

В вашем примере вы сравниваете строковый объект с Nothing (Null), и поскольку операторы =/<> определены для строк, первый пример работает. Однако это не работает, когда встречается Null, потому что строки являются ссылочными типами и могут быть Null. Лучший способ (как вы уже догадались) — последняя версия с использованием Is/IsNot.

person Cerebrus    schedule 16.03.2009

Вот технический ответ (дополняющий ответ Роуленда Шоу).

Ключевое слово Is проверяет, являются ли два операнда ссылками на одну и ту же объектную память, и возвращает значение true только в этом случае. Я считаю, что он функционально эквивалентен Object.ReferenceEquals. Ключевое слово IsNot — это просто сокращенный синтаксис для записи Not ... Is ..., не более того.

Оператор = (равенство) сравнивает значения и в этом случае (как и во многих других) эквивалентен String.Equals. Теперь оператор ‹> (неравенство) не совсем аналогичен ключевым словам Is и IsNot, поскольку его можно переопределить отдельно. от оператора = в зависимости от класса. Я считаю, что дело всегда должно заключаться в том, что он возвращает логическую инверсию оператора = (и, конечно, в случае String), и просто позволяет проводить более эффективное сравнение при проверке на неравенство, а не чем равенство.

При работе со строками, если вы на самом деле не хотите сравнивать ссылки, всегда используйте оператор = (или, я полагаю, String.Equals). В вашем случае, поскольку вы проверяете значение null (Nothing), кажется, вам нужно использовать ключевое слово Is или IsNot (оператор равенства потерпит неудачу, потому что он не может сравнивать значения нулевых объектов). С точки зрения синтаксиса ключевое слово IsNot здесь немного лучше, так что используйте его.

person Noldorin    schedule 16.03.2009

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

person luiscubal    schedule 16.03.2009

Если вам нужно знать, существует ли переменная, используйте Is/IsNot Nothing.

Использование ‹> требует, чтобы для оцениваемой переменной был определен оператор «‹>». Проверить

 Dim b As HttpContext
 If b <> Nothing Then
    ...
 End If

и результирующая ошибка

Error   1   Operator '<>' is not defined for types 'System.Web.HttpContext' and 'System.Web.HttpContext'.   
person hometoast    schedule 16.03.2009

Компиляторы C# и VB.NET часто генерируют разные IL для операций, которые, по-видимому, эквивалентны в обоих языках. Так уж получилось, что C# делает «ожидаемое» действие, когда вы пишете stringvar == null, а VB.NET — нет. Чтобы получить тот же эффект в VB.NET, вы должны установить истинное равенство ссылок с помощью оператора Is.

person Christian Hayter    schedule 28.07.2009

Я полный нуб, я пришел сюда, чтобы выяснить синтаксис VB «не равно», поэтому я решил, что добавлю его сюда, если он кому-то еще понадобится:

<%If Not boolean_variable%>Do this if boolean_variable is false<%End If%>
person Travis Heeter    schedule 01.04.2013

на самом деле Is действительно хорош, так как разработчики могут захотеть переопределить оператор == для сравнения со значением. скажем, у вас есть класс A, оператор == of A предназначен для сравнения некоторого поля A с параметром. тогда у вас возникнут проблемы в С#, чтобы проверить, является ли объект A нулевым со следующим кодом,

    A a = new A();
...
    if (a != null)
it will totally wrong, you always need to use if((object)a != null)
but in vb.net you cannot write in this way, you always need to write
    if not a is nothing then
or
    if a isnot nothing then

что, как сказал Кристиан, vb.net ничего не «ожидает».

person Hzj_jie    schedule 22.06.2013