Ничто не равно String.Empty, null не равно String.Empty, что мне здесь не хватает?

В смешанном проекте кода (VB и С#) мы отлаживали старый код Visual Basic следующим образом:

If Request.Params("xxx") <> "" Then
   'do something

Я считал эту ошибку как Request.Params может быть null, и в этом случае утверждение стало бы ложным, что не было идеей.

Так я думал. Я только что узнал - снова, что VB Nothing и С# null - это не одно и то же, а Nothing - это не то же самое, что null. Фактически:

if(String.Empty == null)          // in C# this is always false (correct)
If String.Empty = Nothing Then    ' in VB this is always true (????)

Как это возможно? Это проблема обратной совместимости?

Ответ 1

Nothing имеет особое значение в VB для строк. Чтобы проверить, является ли ссылка на строку нулевой, вам необходимо:

If value Is Nothing

Из Документация операторов VB сравнения:

Числовые сравнения обрабатывают Ничто как 0. Сравнение строк рассматривает Nothing как "" (пустую строку).

Я подозреваю, что это просто для обратной совместимости с VB6 - это не то, чем я был бы доволен, если бы я был разработчиком VB.

Сравнение формы

If value = Nothing

скомпилирован для вызова Microsoft.VisualBasic.CompilerServices.Operators.CompareString, который возвращает 0 (т.е. равно), если один операнд пуст, а другой пуст.

Ответ 2

В vb6 значением по умолчанию для строковой переменной была пустая строка. Программист vb6, полагающийся на такое поведение, не будет "хуже", чем программист на C, полагающийся на инициализацию переменных по умолчанию по умолчанию; оба поведения были указаны как часть языка.

Кроме того, в COM (структура, на которой основывались предыдущие версии VB6), в любое время, когда была создана ссылка на строку, кому-то придется вручную ее утилизировать. Поскольку наиболее часто используемой строкой была пустая строка, многие методы COM явно документированы как относящиеся к нулевому указателю как эквивалентные пустой строке. Это означает, что функция, возвращающая пустую строку или передающая ее как параметр значения или возвращающий ее, может просто передать нулевой указатель, не выделяя ничего; получатель нулевого указателя тогда не должен будет ничего выделять.

Поскольку объекты в .net не требуют явного освобождения, преимущества производительности относительно нулевой ссылки как пустой строки больше не применяются. Тем не менее, методы, вызываемые из кода, которые могут ожидать поведение, аналогичное поведению методов COM, будут часто рассматривать ссылки на нулевые строки как те же, что и пустые строки.

Ответ 3

Вы хотите

If Not String.IsNullOrEmpty(Request.Params("xxx") Then
    ...
End If

или

if (!String.IsNullOrEmpty(Request.Params("xxx")) {
    ...
}