Я не могу найти однозначного ответа. Начиная с C# 2.0 вы можете объявить
int? i = 125;
как сокращение для
Nullable<int> i = Nullable<int>(123);
Я помню, как где-то читал, что VB.NET не допускает этого ярлыка. Но вот, сегодня я попробовал это в VS 2008, и он работает.
Кто-нибудь знает, было ли так с .NET 2.0 или это было добавлено позже?





Я не знаю истории, но да, это было усовершенствование VS 2008.
System.Nullable был представлен в .Net 2.0 и доступен для VB как общий тип. Вы просто не можете использовать синтаксис, допускающий значение NULL. Итак, в VS 2005 вы можете:
Dim x as Nullable(of Integer)
Я не знаю, работают ли нулевая эквивалентность и бокс для значений NULL в VB 2005, но я подозреваю, что ответ положительный, поскольку команда .Net внесла изменения в CLR 2.0 для выполнения бокса с значениями NULL. Я бы предположил, что VB использует это.
В 2008 году вы, очевидно, можете просто делать:
Dim x as Integer?
он работает в VB 2005 (dotnet 2.0), но уродлив.
Вы не можете использовать его как обычную переменную, я думал, что он может работать как тип объекта, но это не так.
Вместо этого:
dim oInt as object
dim i as integer
if oInt is nothing then
msgbox("int is null")
else
i = cint(oInt)
end if
у вас есть это.
Dim oInt as nullable(of integer)
dim i as integer
if oInt.HasValue = false then
msgbox("int is null")
else
i = oInt.Value
end if
Проблема здесь в том, что если ваша переменная имеет значение NULL, и вы случайно вызываете свойство Value, оно блокирует необработанное исключение.
так, например, мой любимый - это.
AddParamToSQLCmd(sqlCmd, "@SomeID", SqlDbType.Int, 0, ParameterDirection.Input, iif (oInt.HasValue, oInt.Value, DBNull.value))
Приведет к ошибке времени выполнения, если ваше Предполагаемое значение Nullable равно нулю !!!
так что здесь обнуляемый (целочисленный) vs объектный код
допускающий значение NULL (целого числа)
if oInt.HasValue then
AddParamToSQLCmd(sqlCmd, "@SomeID", SqlDbType.Int, 0, ParameterDirection.Input, oInt.Value)
else
AddParamToSQLCmd(sqlCmd, "@SomeID", SqlDbType.Int, 0, ParameterDirection.Input, dbnull.value)
end if
Объект
AddParamToSQLCmd(sqlCmd, "@SomeID", SqlDbType.Int, 0, ParameterDirection.Input, oInt)
Более простой способ добавить параметр - использовать новый оператор If: AddParamToSQLCmd (sqlCmd, «@SomeID», SqlDbType.Int, 0, ParameterDirection.Input, If (oInt.HasValue, oInt.Value , DBNull.value)) Причина, по которой это работает, заключается в том, что If является оператором короткого замыкания, тогда как обе стороны вызова метода IIf оцениваются независимо от того, истинно ли значение первого операнда.
IIRC, типы, допускающие значение NULL, были введены в .NET 2.0 на очень поздней стадии. Команде компилятора C# удалось втиснуть больше языковой поддержки, чем команде VB.NET. Команда VB.NET более или менее догнала VS2008. Вот почему вы можете, например, использовать оператор == для сравнения значений NULL в C# 2.0, тогда как в VB.NET вам пришлось мириться с методом Nullable.Equals (). Grrr.
Нулевой эквивалент и бокс работали в VB 2005. Изменения в 2008 были сосредоточены на добавлении "?" синтаксис и реализация подъема оператора. Однако следует отметить одну вещь: это поддержка символа "?" синтаксис не был добавлен в модель VS Code / Code DOM, поэтому любой созданный дизайнером код, использующий типы, допускающие значение NULL, всегда будет использовать старый общий синтаксис.