vba 选择大小写真
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/794036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Select Case True
提问by Otávio Décio
Apparently this used to be a way in VB6 and VBA to short circuit and execute the first true case:
显然,这曾经是 VB6 和 VBA 中短路并执行第一个真实案例的一种方式:
Select Case True
End Select
Is this still in use (VB.NET) ?
这是否仍在使用(VB.NET)?
回答by Chad Birch
This syntax is often used instead of an If...ElseIfstatement. Some people find it a little easier to read. For example:
这种语法经常用来代替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
The answer is that yes, this still works in VB.NET. Just take care with when you use it, because it's not a "standard programming construct" and may be unfamiliar to people that have to maintain your code in the future.
答案是肯定的,这在 VB.NET 中仍然有效。使用它时要小心,因为它不是“标准的编程结构”,将来必须维护您的代码的人可能不熟悉它。
回答by Patrick McDonald
I'm not sure how this construct offers any advantages over the following:
我不确定这个结构如何提供比以下任何优势:
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
The above structure is short-circuiting, and I don't have to try to work out what it does as it's a standard construct.
上面的结构是短路的,我不必尝试弄清楚它的作用,因为它是一个标准结构。
回答by RolandTumble
Others have already answered that actual question, but I just want to chime in that I use this construct fairly frequently. I think it's often the most readable way of simultaneously testing two boolean conditions:
其他人已经回答了这个实际问题,但我只想说我经常使用这个结构。我认为这通常是同时测试两个布尔条件的最易读的方式:
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
I admit that part of why I find it easily readable is that I do use it, and that I do recall having to parse it the first time I saw it--but once successfully parsed, my reaction was "That's brilliant!"
我承认我觉得它易于阅读的部分原因是我确实使用了它,而且我确实记得我第一次看到它时必须解析它——但是一旦成功解析,我的反应是“太棒了!”
回答by Oorang
There is a lot of confusion on this topic, but to answer the OPs question: Yes, logical evaluation is the same in VB.Net as it is in VB6 as it is in VBA. http://support.microsoft.com/kb/817250
关于这个主题有很多混乱,但要回答 OP 问题:是的,逻辑评估在 VB.Net 中与在 VB6 中和在 VBA 中相同。http://support.microsoft.com/kb/817250
To take advantage of the Select Case optimization technique you use Select Cases inherent syntax to avoid the use of the Logical Operators And, Or, Xor, etc. It is these operators that do have Short Circuit evaluation.
为了利用 Select Case 优化技术,您可以使用 Select Cases 的固有语法来避免使用逻辑运算符 And、Or、Xor 等。正是这些运算符确实具有短路评估。
Consider this example:
考虑这个例子:
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
The Select Case version will only run A. The If-Block will run both. This is not If statement's fault, rather it is the fault of the And operator. If you prefer, you can structure the If Statement to short circuit like this:
Select Case 版本将只运行 A。If-Block 将同时运行两者。这不是 If 语句的错,而是 And 运算符的错。如果您愿意,您可以将 If 语句构造为短路,如下所示:
Public Sub Example2()
If A Then
ElseIf B Then
Beep
End If
End Sub
And B will not run. It's all just a matter of style.
B 不会跑。这只是风格问题。
The important thing to know is that what you are avoiding is the And/Or/Xor Operators not the If-Blocks. If you like the Select Case version of the If-Block better... More power to you:)
要知道的重要一点是,您要避免的是 And/Or/Xor 运算符而不是 If-Blocks。如果你更喜欢 If-Block 的 Select Case 版本...更多的力量给你:)
回答by Neolisk
Select Caseis a powerful operator by itself. But even though Select Case Trueis still supported, it is better to be avoided for maintainability perspective. You always have to justify the need. If needed badly, you can even use DoEventsand GoTo. For the accepted answer, it could have been written like this instead:
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
回答by Pete H.
Do you mean something like this?
你的意思是这样的吗?
Select Case True
Case 1 = 0
Console.Write("1")
Case 1 = 1
Console.Write("2")
Case 2 = 2
Console.Write("3")
End Select
In which, the program would write 2...if that's what you're asking, then yes, that is still around in VB.NET
其中,程序会写 2...如果这就是你要问的,那么是的,它仍然存在于 VB.NET
回答by Dennis Arkwright
Another reason for using the construct SELECT CASE TRUE is when your case statements evaluate to a boolean value. The SELECT CASE needs to have all cases evaluate to the same data type as the control. If you are looking at a string data type, then all of the case statements need to be strings as well.
使用结构 SELECT CASE TRUE 的另一个原因是当您的 case 语句评估为布尔值时。SELECT CASE 需要让所有 case 评估为与控件相同的数据类型。如果您正在查看字符串数据类型,那么所有 case 语句也必须是字符串。
SELECT CASE [string]
CASE "String 1", "String 2"
[do a thing]
CASE "String 3"
[do another thing]
END SELECT
However if you are comparing partial strings using the LIKE operator then your case data type becomes boolean which will not match the string control. The following code will not work:
但是,如果您使用 LIKE 运算符比较部分字符串,那么您的 case 数据类型将变为与字符串控件不匹配的布尔值。以下代码将不起作用:
SELECT CASE [string]
CASE LIKE "*1", "*2"
[do a thing]
CASE LIKE "*3"
[do another thing]
END SELECT
In order to use wildcards (and thus have boolean case outcomes) you have to have a boolean control value, thus the structure needs to be:
为了使用通配符(因此有布尔情况下的结果)你必须有一个布尔控制值,因此结构需要是:
SELECT CASE TRUE
CASE [string] LIKE "*1", "*2"
[do a thing]
CASE [string] LIKE "*3"
[do another thing]
END SELECT
I suppose you could use IF...ELSEIF
我想你可以使用 IF...ELSEIF
IF [string] LIKE "*1" AND [string] LIKE "*2" THEN
[do a thing]
ELSEIF [string] LIKE "*3"
[do another thing]
END IF
Personally I find the SELECT CASE is easier to use and read when there are more than three options. I use IF...ELSE and IF...ELSEIF when I have to evaluate two or three different options (>, =, <) or if I am testing a value for a specific range of 'valid' entries. If instead the entry has more variety and I need to determine which of ten possibilities has happened the SELECT CASE is a much easier construct to use as it eliminates the need for multiple OR statements.
我个人认为 SELECT CASE 在有超过三个选项时更易于使用和阅读。当我必须评估两个或三个不同的选项(>、=、<)或者我正在测试特定范围的“有效”条目的值时,我会使用 IF...ELSE 和 IF...ELSEIF。相反,如果条目有更多种类并且我需要确定发生了十种可能性中的哪一种,则 SELECT CASE 是一个更容易使用的构造,因为它消除了对多个 OR 语句的需要。
回答by x77
You can define Equals Operator on any Wrapper Type. Then you can use Wrapper type on Select Case.
您可以在任何包装器类型上定义等于运算符。然后您可以在 Select Case 上使用 Wrapper 类型。
Sample 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
Now you can use _is(AnyObject):
现在您可以使用 _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
About Performance.Release Code is optimized. Wrapper has no performance penalty.
关于性能。发布代码已优化。包装器没有性能损失。
回答by Paul
After reading this thread, it appears that the primary argument for Select Case Trueis readability. Is this enough? When I first saw the construct used like this in VB.NET, I had to read over it a few times to make sure I'd got the gist of it, but still thought along the same lines as RolandTumble, above. So even readability comes at a slight cost. Everyone knows what an If...ElseIf...End Ifstatement is and why it's there. Short circuiting can be aided using AndAlsoor OrElse, and complexity is purely down to the code and coder involved.
阅读此线程后,似乎主要论点Select Case True是可读性。这够了吗?当我第一次在 VB.NET 中看到像这样使用的构造时,我不得不通读它几次以确保我掌握了它的要点,但仍然按照与上面的 RolandTumble相同的思路进行思考。因此,即使是可读性也要付出很小的代价。每个人都知道什么是If...ElseIf...End If语句以及它为什么存在。可以使用AndAlso或辅助短路OrElse,并且复杂性完全取决于所涉及的代码和编码器。
Even Ifstatements can be optimised. What's the point in asking the obvious (whether your value = True). I was once asked what the following did by a coder working with us...
甚至If可以优化语句。询问显而易见的事情(无论您的value = True)有什么意义。曾经与我们一起工作的编码员曾问我以下做了什么......
Dim isVisible As Boolean
....
If isVisible Then
....
End If
The use of the Select Case Truestructure also feels like you're moving the focus or the comparison emphasis away from the actual Select Caseline and into the Casestatements, as odd as that may sound.
Select Case True结构的使用也感觉就像您将重点或比较重点从实际Select Case行转移到Case陈述中,尽管听起来很奇怪。

