Выберите Case True - PullRequest
       25

Выберите Case True

18 голосов
/ 27 апреля 2009

По-видимому, в VB6 и VBA это был путь к короткому замыканию и выполнению первого истинного случая:

Select Case True
End Select

Это все еще используется (VB.NET)?

Ответы [ 9 ]

28 голосов
/ 27 апреля 2009

Этот синтаксис часто используется вместо оператора If...ElseIf. Некоторые люди находят это немного легче читать. Например:

Select Case True
    Case testVariable < 0
         Console.Write("You must supply a positive value.")
    Case testVariable > 10
         Console.Write("Please enter a number from 0-10.")
    Case True
         Call DoWork(testVariable)
End Select

Ответ - да, это все еще работает в VB.NET. Просто будьте осторожны при его использовании, потому что это не «стандартная программная конструкция» и может быть незнакомым людям, которым придется поддерживать ваш код в будущем.

13 голосов
/ 27 апреля 2009

Я не уверен, как эта конструкция дает какие-либо преимущества перед следующими:

If testVariable < 0 Then
     Console.Write("You must supply a positive value.")
ElseIf testVariable > 10 Then
     Console.Write("Please enter a number less than 10.")
Else
     Call DoWork(testVariable)
End If

Приведенная выше структура имеет короткое замыкание, и мне не нужно пытаться понять, что она делает, поскольку это стандартная конструкция.

11 голосов
/ 27 апреля 2009

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

Dim A As Boolean
Dim B As Boolean
'
'do stuff to set values of A and B
'
Select Case True
  Case A And B
    'something
  Case A And Not B
    'something else
  Case Not A And B
    'you get the picture
  Case Else
    '...
End Select

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

9 голосов
/ 12 ноября 2009

В этой теме много путаницы, но для ответа на вопрос OP: Да, логическая оценка в VB.Net такая же, как и в VB6, как и в VBA. http://support.microsoft.com/kb/817250

Чтобы воспользоваться техникой оптимизации Select Case, вы используете собственный синтаксис Select Cases, чтобы избежать использования логических операторов And, Or, Xor и т. Д. Именно эти операторы имеют оценку короткого замыкания.

Рассмотрим этот пример:

Public Sub Example()
    If A Or B Then
        Beep
    End If
    Select Case True
        Case A, B
            Beep
    End Select
End Sub

Private Function A() As Boolean
Debug.Print "A Ran"
    A = True
End Function

Private Function B() As Boolean
Debug.Print "B Ran"
    B = False
End Function

Версия Select Case будет запускаться только A. If-Block будет запускать оба. Это не ошибка оператора, скорее, это ошибка оператора And. Если вы предпочитаете, вы можете структурировать оператор If для короткого замыкания следующим образом:

Public Sub Example2()
    If A Then
    ElseIf B Then
        Beep
    End If
End Sub

И Б не побежит. Это всего лишь вопрос стиля.

Важно знать, что вы избегаете операторов And / Or / Xor, а не блоков If. Если вам больше нравится версия If-блока в Select Case ... Больше возможностей:)

3 голосов
/ 20 октября 2012

Select Case является мощным оператором сам по себе . Но даже если Select Case True все еще поддерживается, его лучше избегать с точки зрения удобства обслуживания. Вы всегда должны оправдать необходимость. При необходимости вы можете использовать DoEvents и GoTo. Для принятого ответа его можно было бы написать так:

Select Case testVariable
  Case Is < 0 : Console.Write("You must supply a non-negative value.")
  Case Is > 10 : Console.Write("Please enter a number from 0-10.")
  Case Else : Call DoWork(testVariable)
End Select
3 голосов
/ 27 апреля 2009

Вы имеете в виду что-то подобное?

 Select Case True
    Case 1 = 0
        Console.Write("1")
    Case 1 = 1
        Console.Write("2")
    Case 2 = 2
        Console.Write("3")
End Select

В котором программа напишет 2 ... если это то, что вы спрашиваете, то да, это все еще существует в VB.NET

2 голосов
/ 05 марта 2015

Вы можете определить оператор Equals для любого типа оболочки. Тогда вы можете использовать тип Wrapper в Select Case.

Образец оболочки.

Imports System.Runtime.InteropServices
<DebuggerStepThrough()> Friend Module Util
  Public Function _Is(v As Object) As IsWrapper
      Return New IsWrapper With {.Obj = v}
  End Function
  Public Structure IsWrapper
     Public Obj As Object
     Public Shared Operator =(ByVal a As IsWrapper, ByVal b As Object) As Boolean
         Return a.Obj Is b
     End Operator
     Public Shared Operator <>(ByVal a As IsWrapper, ByVal b As Object) As Boolean
         Return a.Obj IsNot b
     End Operator
  End Structure
End Module

Теперь вы можете использовать _is (AnyObject):

Private Sub RbClass_CheckedChanged(sender As System.Object, e As System.EventArgs)
    If DirectCast(sender, RadioButton).Checked = False Then Return
    Select Case _Is(sender)
        Case RbClass : Rb = 0
        Case RbTablePredicate : Rb = 1
        Case RbTableRowFilter : Rb = 2
    End Select
    QueryCtl1_QueryChanged(Nothing, Nothing)
End Sub

Public Sub Predicate(ByVal PredicateType As Type, ByVal Op As Operadores, ByVal Obj As Object, ByVal CompareOptions As CompareOptions, ByVal Fnc As [Delegate])
   Dim pred As [Delegate] = Nothing
   Select Case _Is(PredicateType)
      Case GetType(Boolean)
          pred = New Predicate(Of Boolean)(Function(v) v)
      Case GetType(String)
          pred = StrPredicate(Op, Obj, CompareOptions)
      Case Else 'Utilizar Generics
          pred = GenericHelper.Builder(PredicateType).Predicate(Op, Obj)
   End Select
   Predicate(pred, Fnc)
End Sub

О производительности. Код выпуска оптимизирован. Обертка не имеет штрафа за производительность.

1 голос
/ 11 января 2017

Другая причина использования конструкции SELECT CASE TRUE - когда ваши операторы case оцениваются как логическое значение. В случае SELECT CASE все случаи должны соответствовать одному типу данных в качестве элемента управления. Если вы смотрите на строковый тип данных, то все операторы case также должны быть строками.

SELECT CASE [string]
CASE "String 1", "String 2"
    [do a thing]
CASE "String 3"
    [do another thing]
END SELECT

Однако если вы сравниваете частичные строки с помощью оператора LIKE, тогда ваш тип данных дела становится логическим, что не будет соответствовать строковому элементу управления. Следующий код не будет работать:

SELECT CASE [string]
CASE LIKE "*1", "*2"
    [do a thing]
CASE LIKE "*3"
    [do another thing]
END SELECT

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

SELECT CASE TRUE
CASE [string] LIKE "*1", "*2"
    [do a thing]
CASE [string] LIKE "*3"
    [do another thing]
END SELECT

Полагаю, вы могли бы использовать IF ... ELSEIF

IF [string] LIKE "*1" AND [string] LIKE "*2" THEN
    [do a thing]
ELSEIF [string] LIKE "*3"
    [do another thing]
END IF

Лично я считаю, что SELECT CASE легче использовать и читать, когда имеется более трех вариантов. Я использую IF ... ELSE и IF ... ELSEIF, когда мне нужно оценить два или три различных варианта (>, =, <) или если я проверяю значение для определенного диапазона «допустимых» записей. Если вместо этого запись имеет больше разнообразия, и мне нужно определить, какая из десяти возможностей произошла, SELECT CASE - гораздо более простая конструкция, поскольку она устраняет необходимость в нескольких операторах OR. </p>

1 голос
/ 14 декабря 2015

После прочтения этой темы выясняется, что основным аргументом для Select Case True является удобочитаемость. Этого достаточно? Когда я впервые увидел такую ​​конструкцию, используемую в VB.NET, мне пришлось несколько раз прочитать ее, чтобы убедиться, что я понял ее суть, но все же подумал о том же, что и RolandTumble, выше . Таким образом, даже удобочитаемость достигается за небольшую плату. Все знают, что такое If...ElseIf...End If утверждение и почему оно там. Короткому замыканию можно помочь, используя AndAlso или OrElse, а сложность зависит только от кода и задействованного кодера.

Даже If операторы могут быть оптимизированы. Какой смысл спрашивать очевидное (будь то value = True). Однажды меня спросили, что делает следующий кодер, работающий с нами ...

Dim isVisible As Boolean
....
If isVisible Then
    ....
End If

Использование структуры Select Case True также означает, что вы перемещаете фокус или акцент сравнения с фактической линии Select Case в операторы Case, как бы странно это не звучало.

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