有条件地跳过案例

Posted

技术标签:

【中文标题】有条件地跳过案例【英文标题】:Conditionally skip cases 【发布时间】:2013-08-07 01:32:02 【问题描述】:

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 块中使用。

这可以吗?我应该与谁交谈才能实现这一目标?

编辑 (1/2)

重要的是此代码将首先评估When &lt;expression&gt;。只有当它评估为True,它才会继续评估Case &lt;expression&gt;

我想这样做的主要原因是因为我想编写测试条件在情况正确(或错误,取决于你如何看待它)时抛出异常的案例。如果前提条件为真,我想跳过这些情况。

编辑 (2/2)

现在很清楚,我所要求的在当前的 VB 迭代中是不可能的。所以我搜索了一个地方来向 .NET 开发团队提交功能请求,然后发现他们有一个用户语音平台。

长话短说:如果您希望看到这个实现,请点击此页面上的投票按钮:https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4274712-add-when-keyword-support-to-select-case-stat

【问题讨论】:

可能我没有准确理解您的意思 - 为什么不使用 linq 而不是 Select-Case 语句? 另一种选择是直接跳过Select,然后执行If includeEvenNumbers AndAlso number Mod 2 = 0 Then Console.WriteLine(number) Else If includeOddNumbers AndAlso number Mod 2 &lt;&gt; 0 Then Console.WriteLine(number) End If之类的操作? @Rex 您如何将 linq 融入其中? @Tim 这实际上是我在真实代码中所做的。不是上面那个愚蠢的例子。我只是不喜欢有 3+ ElseIfs 在你本来可以使用开关但不能使用的地方。 【参考方案1】:

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

编辑:使其更简单:

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

【讨论】:

我可以看到 linq 是如何用更少的代码解决这个特定问题的,但是如果问题发生了变化,那么我可以重新开始。 是的,如果你有很多条件,它可能会变得非常复杂。但是,如果您有很多条件做不同的事情,为什么不将每个任务包装在具有不同标准的不同类中呢?通常,您将拥有具有指定标准的任务集合,然后将数据集合作为上下文传递给整个任务......相信它会更易于维护,不是吗?【参考方案2】:

通过使用枚举而不是 2 个布尔值,您只需要一个 if 语句即可完成 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)

【讨论】:

很好,尽管这并不能说明用户想要同时打印偶数和奇数的情况。但无论如何,我并不想把重点放在解决我给出的例子上。我写它只是为了展示我的目标。 我添加了代码来做这两件事。我的回答应该更冗长。虽然这确实解决了您的示例,但它也证明了当某个构造无法完成您想要的工作时,可能是时候退后一步并重新检查您的方法了。这种特殊方法适用于需要满足多个不同条件的许多情况。 我完全同意,但这不是我想要说明的重点。我已经在前两个代码块中证明了Select...Case 可以处理这个特定的工作。第三个块更短,更容易理解,如果使用得当,性能可能会更好。

以上是关于有条件地跳过案例的主要内容,如果未能解决你的问题,请参考以下文章

我可以有条件地跳过在同一个文件中加载“更多”红宝石代码吗?

如何有条件地跳过python中for循环中的迭代步骤数?

如何有条件地跳过 Grails Spring Security 插件过滤器链中的 SecurityContextPersistenceFilter 过滤器

跳过测试和预期失败.py

unittest---unittest跳过用例

Python+selenium之跳过测试和预期失败