Вам нужно несколько операторов Else, если вы запускаете несколько операторов If в одну строку? - PullRequest
1 голос
/ 12 февраля 2020

У меня есть оператор, который выполняет две проверки If в одной строке:

If JMdict(i).Senses.Count > 0 Then If JMdict(i).Senses.First.Gloss.Count > 0 Then meaning = JMdict(i).Senses.First.Gloss.First Else meaning = ""

Мне интересно, нужно ли мне добавить второй Else, как показано ниже:

If JMdict(i).Senses.Count > 0 Then If JMdict(i).Senses.First.Gloss.Count > 0 Then meaning = JMdict(i).Senses.First.Gloss.First Else meaning = "" Else meaning = ""

Или первый Else покроет все пути кода?

По сути, я должен делать

If [First Condition] Then If [Second Condition] Then [Result] Else [Nothing happens]

или

If [First Condition] Then If [Second Condition] Then [Result] Else [Nothing happens] Else [Nothing happens]

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

Ответы [ 2 ]

2 голосов
/ 12 февраля 2020

Ваш код

If JMdict(i).Senses.Count > 0 Then If JMdict(i).Senses.First.Gloss.Count > 0 Then meaning = JMdict(i).Senses.First.Gloss.First() Else meaning = ""

является коротким для этого

If JMdict(i).Senses.Count > 0 Then 
    If JMdict(i).Senses.First.Gloss.Count > 0 Then 
        meaning = JMdict(i).Senses.First.Gloss.First() 
    Else 
        meaning = ""
    End If
End If

Так что если JMdict(i).Senses.Count <= 0, то значение не будет установлено.

Я мог бы сделать это, используя короткое замыкание AndAlso , как вы упомянули

If JMdict(i).Senses.Any() AndAlso JMdict(i).Senses.First().Gloss.Any() Then meaning = JMdict(i).Senses.First().Gloss.First() Else meaning = ""

или используйте If(), который немного сокращает код

meaning = If(JMdict(i).Senses.Any() AndAlso JMdict(i).Senses.First().Gloss.Any(), JMdict(i).Senses.First().Gloss.First(), "")

Использование If() делает его очень Ясно, что значение будет установлено, потому что мы начинаем с meaning =

. Для людей с нарушением чтения функцию If() можно разбить на несколько строк

meaning = If(JMdict(i).Senses.Any() AndAlso JMdict(i).Senses.First().Gloss.Any(),
             JMdict(i).Senses.First().Gloss.First(), 
             "")

Вы также можете использовать If() как оператор нулевого слияния. Обратите внимание, что эта версия If() принимает только два аргумента

meaning = If(JMdict(i).Senses.FirstOrDefault()?.Gloss.FirstOrDefault(), "")
1 голос
/ 12 февраля 2020

Блок Else в этой отдельной строке будет НЕ работать во всех случаях. Это помогает понять, почему, если вы ожидаете, что код состоит из нескольких строк:

If JMdict(i).Senses.Count > 0 Then 
    If JMdict(i).Senses.First.Gloss.Count > 0 Then 
        meaning = JMdict(i).Senses.First.Gloss.First 
    Else 
        meaning = ""
    End If
    'There's no Else block for this spot!
End If

Чтобы исправить это, у вас есть несколько вариантов. У нас может быть два Else блока (не фанат этого):

If JMdict(i).Senses.Count > 0 Then 
    If JMdict(i).Senses.First.Gloss.Count > 0 Then 
        meaning = JMdict(i).Senses.First.Gloss.First 
    Else 
        meaning = ""
    End If
Else
    meaning = ""
End If

Или мы можем использовать AndAlso:

If JMdict(i).Senses.Count > 0 AndAlso JMdict(i).Senses.First.Gloss.Count > 0 Then 
    meaning = JMdict(i).Senses.First.Gloss.First 
Else 
    meaning = ""
End If

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

If JMdict(i).Senses.Count > 0 AndAlso JMdict(i).Senses.First.Gloss.Count > 0 Then meaning = JMdict(i).Senses.First.Gloss.First Else meaning = ""

IMO, вышеприведенное помещает слишком много в одно выражение, где вы должны прокручивать или путать с разрывами строк, чтобы понять это. Давайте поработаем над тем, чтобы сократить его до чего-то, что мы действительно можем прочитать и разобрать как человека. Я начну с условного оператора If():

meaning = If(JMdict(i).Senses.Count > 0 AndAlso JMdict(i).Senses.First.Gloss.Count > 0, JMdict(i).Senses.First.Gloss.First, "")

Это немного лучше, но только немного (128 символов против 145). Мы можем переместить часть этого текста в дополнительную строку, чтобы задать значение сразу, а затем перезаписать его, только если условие соответствует:

meaning = ""
If JMdict(i).Senses.Count > 0 AndAlso JMdict(i).Senses.First.Gloss.Count > 0 Then meaning = JMdict(i).Senses.First.Gloss.First

Хммм. Не так много улучшений. Это сработало бы лучше в C#. Это шаг, хотя. Отсюда мы также можем использовать несколько другие операторы Linq и нулевые условные выражения для дальнейшего упрощения:

meaning = JMdict(i).Senses.FirstOrDefault()?.Gloss?.FirstOrDefault()
If meaning Is Nothing Then meaning = ""

Наконец, мы начинаем получать что-то, что является разумным количеством кода, который человек может обработать и понять , Кроме того, мы можем уменьшить его еще больше, используя нуль-коалесцирующий If() вариант :

meaning = If(JMdict(i).Senses.FirstOrDefault()?.Gloss?.FirstOrDefault(), "")

Теперь это мне нравится. Одна строка, без прокрутки. Существуют некоторые расширенные функции, которые может знать не каждый программист на VB. Net, но даже если вы им не являетесь, вы все равно сможете следить за тем, что делает код.

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