2013-08-07 3 views
0

В заявлении Select...Case есть ли способ пропускать чеки на основе предусловия?Условно пропускать чехлы

Что я делаю сейчас, используя невероятно глупый пример:

Private Sub PrintNumbers(includeEvenNumbers As Boolean, includeOddNumbers As Boolean) 
    For number As Integer = 0 To 9 
     Select Case number 
      Case 0, 2, 4, 6, 8 
       If includeEvenNumbers Then 
        Console.WriteLine(number) 
       End If 
      Case 1, 3, 5, 7, 9 
       If includeOddNumbers Then 
        Console.WriteLine(number) 
       End If 
     End Select 
    Next 
End Sub 

Иногда я даже писать свои дела наизнанку:

Private Sub PrintNumbers(includeEvenNumbers As Boolean, includeOddNumbers As Boolean) 
    For number As Integer = 0 To 9 
     Select Case True 
      Case includeEvenNumbers 
       If number Mod 2 = 0 Then 
        Console.WriteLine(number) 
       End If 
      Case includeOddNumbers 
       If number Mod 2 <> 0 Then 
        Console.WriteLine(number) 
       End If 
     End Select 
    Next 
End Sub 

То, что я действительно хотел бы сделать вместо:

Private Sub PrintNumbers(includeEvenNumbers As Boolean, includeOddNumbers As Boolean) 
    For number As Integer = 0 To 9 
     Select Case number 
      Case 0, 2, 4, 6, 8 When includeEvenNumbers 
       Console.WriteLine(number) 
      Case 1, 3, 5, 7, 9 When includeOddNumbers 
       Console.WriteLine(number) 
     End Select 
    Next 
End Sub 

Обратите внимание, что я использовал When ключевое слово, которое в настоящее время используется только в Try...Catch блоков.

Можно ли это сделать? С кем я общаюсь, чтобы это произошло?

EDIT (1/2)

Что важно то, что этот код будет первым оценить When <expression>. Только если он оценивается до True, он будет продолжать оценивать Case <expression>.

Основная причина, по которой я хочу сделать это, - это то, что я хотел бы написать случаи, когда условие теста выдает исключение, если обстоятельства правильные (или неправильные, в зависимости от того, как вы на это смотрите). Я бы хотел пропустить эти случаи, если условие является истинным.

EDIT (2/2)

Это довольно ясно теперь, что я прошу не возможно в текущей итерации VB. Поэтому я искал место для отправки запросов функций в команду разработчиков .NET, а затем выяснил, что у них есть платформа пользовательского обслуживания.

Короче говоря: если вы хотите, чтобы это реализовать, нажмите кнопку голосов на этой странице: https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4274712-add-when-keyword-support-to-select-case-stat

+0

, вероятно, я не уловил вашу точку именно - почему бы не использовать LINQ вместо Select-Case заявление? – Rex

+1

Другой вариант - просто пропустить 'Select' и сделать что-то вроде' If includeEvenNumbers AndAlso number Mod 2 = 0 Then Console.WriteLine (number) Else If includeOddNumbers AndAlso number Mod 2 <> 0 Then Console.WriteLine (number) End If'? – Tim

+0

@Rex как бы вы поместили linq в это? –

ответ

0

пример: LINQ

Dim condition As Predicate(Of Integer) = Nothing 
    If includeEvenNumbers Then 
     condition = Function(x) x Mod 2 = 0 
    Else 
     condition = Function(x) x Mod 2 = 1 
    End If 

    For Each item In Enumerable.Range(0, 8).Where(condition) 
     ' do what ever you like here... 
    Next 

EDIT: чтобы сделать его проще:

For Each item In Enumerable.Range(0, 8).Where(Function(x) x Mod 2 = If(includeEvenNumbers, 0, 1)) 
    ' do what ever you like here... 
Next 
+0

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

+0

Да, это может стать очень сложным, если у вас много условий. но если у вас много условий, делающих разные вещи, почему бы не обернуть каждую задачу в другом классе с разными критериями? как правило, у вас будут сводки задач с указанными критериями, а затем передайте сбор данных как контекст во всех задачах ... верьте, что он будет более ремонтопригодным, не так ли? – Rex

0

Используя enum вместо 2 булевых, вам нужно только одно заявление, чтобы выполнить проверку состояния 2. Что-то вроде этого:

Public Enum Include 
    Odd = 1 
    Even = 2 
    Both = 0 
End Enum 
Private Sub PrintNumbers(includenumbers As Include) 
    For I = 1 To 10 
     If includenumbers = Include.Both OrElse I Mod 2 = includenumbers Mod 2 Then 
      TextBox2.AppendText(I.ToString) 
     End If 
    Next 
End Sub 

Вы назвали бы это так:

PrintNumbers(Include.Odd) 
+0

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

+0

Я добавил код, чтобы сделать оба. Я должен был быть более подробным в своем ответе. Хотя это и решает ваш пример, он также демонстрирует, что, когда определенная конструкция не может выполнить требуемую работу, возможно, настало время отступить и пересмотреть ваш подход. Этот конкретный подход будет работать для многих ситуаций, когда вам нужно несколько разных условий. – tinstaafl

+0

Я полностью согласен, но это, кроме того, что я пытаюсь сделать. Я уже доказал в первых двух блоках кода, что 'Select ... Case' может обрабатывать эту конкретную работу. Третий блок просто короче, легче понять и, вероятно, будет работать лучше, если его использовать правильно. –

Смежные вопросы