Точка нотации «Null-Safe» в VB.NET ... или она существует на каком-либо языке? «безопасный оператор разыменования» или эквивалент с использованием LINQ? - PullRequest
3 голосов
/ 21 марта 2011

Я ищу "безопасную" нотацию в VB.net.Существует ли такая вещь - в VB.NET или на любом другом языке?Я хочу, чтобы при использовании устаревших устаревших объектов я мог решить такую ​​проблему, как:

", если есть план, если естьв случае, если у него есть человек, его супруга, иначе, ничего (VBSpeak for Null). "

и избегайте этого:

Dim Spouse as Person = Nothing
if Case.Plan isnot nothing then
    if Case.Plan.Person isnot Nothing
        Spouse = Case.Plan.Person.Spouse
    end if
end if

и сделайте это:

Dim Spouse as Person = Case~Plan~Person~Spouse

Где '~' - это моя искомая «безопасная» точечная нотация, которая мгновенно возвращает ноль при обнаружении первого нулевого объекта вместо того, чтобы выдавать исключение?

Чаще встречается в этойкурс:

dim MyVar as string = XMLDoc.DocumentElement.SelectSingleNode("Name").InnerText

и желание Ничего вместо исключения, когда Имя не существует.

Редактировать:

Есть ли способ решить эту проблему с помощью LINQ для объектов или LINQ для XML?

Ответы [ 4 ]

2 голосов
/ 08 августа 2015

VB.NET 14 представил нуль-условный оператор для решения этой проблемы.Этот оператор также имеет короткое замыкание.

Dim Spouse as Person = Case?.Plan?.Person?.Spouse

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

1 голос
/ 21 марта 2011

В версиях VB, предшествующих 14 (Visual Studio 2015), нет нулевых безопасных точечных обозначений.

Лучший способ справиться с возможными нулевыми значениями, не имея слишком много ifs, - это использовать AndAlso (короткое замыкание And):

If Case.Plan IsNot Nothing _
AndAlso Case.Plan.Person IsNot Nothing _
AndAlso Case.Plan.Person.Name = "Something" Then
    'Do something here
End If

Другим вариантом является использование Null Object Pattern . Но это было бы возможно только с вашими собственными типами данных и потребовало бы некоторых изменений в вашем коде.

Edit:

Чтобы ответить на ваш вопрос о LINQ, это не поможет вам в этом. Цель LINQ - помочь вам запрашивать наборы данных (списки, массивы и т. Д.). Если вы попытаетесь запросить данные с помощью LINQ, у вас возникнет та же проблема, если один из ваших объектов будет нулевым.

1 голос
/ 21 марта 2011

Это все о синтаксисе VB.NET, в нем нет ничего похожего на оператор слияния нуля, как в C # ??оператор.Функция Iif () может писать более компактные операторы If, но они редко работают с нулевыми ссылками, поскольку оба аргумента оцениваются.

В общем, попробуйте использовать нулевые ссылки в качестве средства отладки.Они выдают приятное исключение, когда какой-то другой код, который вы не написали, вызывает ваш, но испортил что-то вроде инициализации.Тихо распространяющиеся программные ошибки приводят к трудностям в диагностике сбоев.Как и исключение NullReferenceException, которое далеко от причины.Или хуже, плохие данные.Возможно, вы могли бы обратиться к своему сценарию с помощью NotAPlan и объекта NoSpouse, объектов, которые существуют исключительно для исключения исключений с нулевой ссылкой и логически означают «план не назначен, супруг не определен».Ссылка, которая может быть нулевой, в противном случае является ничем иным, как ссылкой + логическим значением.Не пропустите bool.

1 голос
/ 21 марта 2011

Я обычно использовал методы расширения для такого рода вещей, очень похожие на то, на что указывает AakashM. Хорошим примером этого является строка ДЛИНА. Поскольку функция LENGTH является методом экземпляра, если вы вызовете ее для объекта с нулевой строкой, вы выбросите ее.

Но закодируйте метод расширения LEN в строковом классе, который проверяет на нулевое значение, и вы можете получить его возвращающим 0 (я считаю, что длина нулевых строк равна 0 практически все время, но это тема для другого потока.)

Используя ту же логику, вы можете реализовать IsNotNull или, возможно, IsValid. основной проблемой будет «остановка» продолжения разрешения свойства (скажем, от случая к плану)

методы в вышеупомянутом потоке используют Lambdas, который выдает довольно громоздкий синтаксис, если вы спросите меня. Я подозреваю, что было бы возможно, если бы тест IsNotNull дал ноль, вернуть объект Proxy, который заменяет нуль, и просто разрешил бы любой вызов метода, который вы делаете для него, также нулевым. Но для этого потребуется динамический прокси, который сам по себе грязный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...