Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Проверяет значение левого операнда для null (Nothing
) перед выполнением операции доступа к члену (?.
) или индекса (?()
), возвращает значение Nothing
, если левый операнд оценивается Nothing
. Обратите внимание, что в выражениях, которые обычно возвращают типы значений, оператор null-условно возвращает значение Nullable<T>.
Эти операторы помогают создавать меньше кода для обработки проверок NULL, особенно при убыванию в структуры данных. Рассмотрим пример.
' Nothing if customers is Nothing
Dim length As Integer? = customers?.Length
' Nothing if customers is Nothing
Dim first As Customer = customers?(0)
' Nothing if customers, the first customer, or Orders is Nothing
Dim count As Integer? = customers?(0)?.Orders?.Count()
Для сравнения альтернативный код для первого из этих выражений без условного оператора NULL:
Dim length As Integer?
If customers IsNot Nothing Then
length = customers.Length
Else
length = Nothing
End If
Иногда необходимо выполнить действие для объекта, который может иметь значение NULL, в зависимости от значения логического элемента для этого объекта (например, логическое свойство IsAllowedFreeShipping
в следующем примере):
Dim customer = FindCustomerByID(123) 'customer will be Nothing if not found.
If customer IsNot Nothing AndAlso customer.IsAllowedFreeShipping Then
ApplyFreeShippingToOrders(customer)
End If
Вы можете сократить код и избежать ручной проверки на значение NULL с помощью оператора NULL, как показано ниже.
Dim customer = FindCustomerByID(123) 'customer will be Nothing if not found.
If customer?.IsAllowedFreeShipping Then ApplyFreeShippingToOrders(customer)
Операторы с условием NULL предусматривают сокращенную обработку. Если одна операция в цепочке условного доступа к члену и операции индексов возвращается Nothing
, остальная часть выполнения цепочки останавливается. В следующем примере C(E)
не вычисляется, если A
B
, или C
вычисляется значение Nothing
.
A?.B?.C?(E)
Обратите внимание, что если Not someStr?.Contains("some string")
или какое-либо другое значение, которое оценивается как Boolean?
значение nothing
или HasValue=false
else
, блок выполняется. Оценка следует оценке SQL, где значение NULL/nothing не равно ничего, а не даже другое значение NULL/nothing.
Другим способом, используемым для доступа к члену с значением NULL, является вызов делегатов в потокобезопасном режиме с гораздо меньшим количеством кода. В следующем примере определяются два типа, a NewsBroadcaster
и a NewsReceiver
. Новости отправляются получателю делегатом NewsBroadcaster.SendNews
.
Public Module NewsBroadcaster
Dim SendNews As Action(Of String)
Public Sub Main()
Dim rec As New NewsReceiver()
Dim rec2 As New NewsReceiver()
SendNews?.Invoke("Just in: A newsworthy item...")
End Sub
Public Sub Register(client As Action(Of String))
SendNews = SendNews.Combine({SendNews, client})
End Sub
End Module
Public Class NewsReceiver
Public Sub New()
NewsBroadcaster.Register(AddressOf Me.DisplayNews)
End Sub
Public Sub DisplayNews(newsItem As String)
Console.WriteLine(newsItem)
End Sub
End Class
Если в списке SendNews
вызовов нет элементов, SendNews
делегат создает исключение NullReferenceException. Перед условными операторами NULL код, как показано ниже, убедитесь, что список вызовов делегата не Nothing
был:
SendNews = SendNews.Combine({SendNews, client})
If SendNews IsNot Nothing Then
SendNews("Just in...")
End If
Новый способ гораздо проще:
SendNews = SendNews.Combine({SendNews, client})
SendNews?.Invoke("Just in...")
Новый способ является потокобезопасной, так как компилятор создает код для оценки SendNews
только один раз, сохраняя результат во временной переменной. Необходимо явным образом вызвать Invoke
метод, так как синтаксис вызова с условным значением SendNews?(String)
NULL отсутствует.