По-видимому, это было способом в VB6 и VBA для короткого замыкания и выполнения первого истинного случая:
Select Case True
End Select
Это все еще используется (VB.NET)?
По-видимому, это было способом в VB6 и VBA для короткого замыкания и выполнения первого истинного случая:
Select Case True
End Select
Это все еще используется (VB.NET)?
Этот синтаксис часто используется вместо оператора 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. Просто позаботьтесь о том, когда вы его используете, потому что это не "стандартная конструкция программирования" и может быть незнакомой людям, которые должны поддерживать ваш код в будущем.
Я не уверен, как эта конструкция предлагает какие-либо преимущества по сравнению с следующим:
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
Вышеупомянутая структура является короткозамкнутой, и мне не нужно пытаться определить, что она делает, как стандартную конструкцию.
Другие уже ответили на этот вопрос, но я просто хочу прослушивать, что я использую эту конструкцию довольно часто. Я думаю, что это часто самый читаемый способ одновременного тестирования двух булевых условий:
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
Я признаю, что часть того, почему я нахожу это легко читаемым, - это то, что я его использую, и что я действительно помню, что нужно было его разобрать в первый раз, когда я это видел, но однажды успешно разобрался, моя реакция была "Это блестяще!"
Существует много путаницы в этой теме, но для ответа на вопрос OP: Да, логическая оценка в VB.Net одинакова, как в VB6, так и в VBA. http://support.microsoft.com/kb/817250
Чтобы воспользоваться преимуществами метода выбора Case Case, вы используете встроенный синтаксис Select Cases, чтобы избежать использования логических операторов And, Or, Xor и т.д. Эти операторы имеют оценку Short Circuit.
Рассмотрим следующий пример:
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 будет работать как. Это не ошибка оператора If, скорее это ошибка оператора And. Если вы предпочитаете, вы можете структурировать оператор If для короткого замыкания следующим образом:
Public Sub Example2()
If A Then
ElseIf B Then
Beep
End If
End Sub
И B не будет работать. Все дело в стиле.
Важно знать, что вы избегаете операторов And/Or/Xor, а не If-Blocks. Если вам нравится версия варианта выбора If-Block лучше... Больше энергии для вас:)
Вы имеете в виду что-то вроде этого?
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
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
Вы можете определить Equals Operator для любого типа Wrapper. Затем вы можете использовать тип Wrapper в Select Case.
Образец Wrapper.
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
О производительности. Оптимизирован код выпуска. У Wrapper нет штрафа за производительность.
После прочтения этого потока, кажется, что основной аргумент для 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
, как это ни странно, как это может звучать.
Другая причина использования конструкции 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, тогда ваш тип данных case становится логическим, который не будет соответствовать строковому управлению. Следующий код не будет работать:
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.