那么,它有哪些隐藏的或较少人知道的功能呢?
Exception When
从句很少被使用。Public Sub Login(host as string, user as String, password as string, _
Optional bRetry as Boolean = False)
Try
ssh.Connect(host, user, password)
Catch ex as TimeoutException When Not bRetry
''//Try again, but only once.
Login(host, user, password, True)
Catch ex as TimeoutException
''//Log exception
End Try
End Sub
Enum
VB 中一个真正的隐藏功能是 completionlist
XML 文档标签,可以用它创建具有扩展功能的自定义 Enum
-like 类型。然而,在C#中该功能并不起作用。
以下是我最近代码中的一个示例:
'
''' <completionlist cref="RuleTemplates"/>
Public Class Rule
Private ReadOnly m_Expression As String
Private ReadOnly m_Options As RegexOptions
Public Sub New(ByVal expression As String)
Me.New(expression, RegexOptions.None)
End Sub
Public Sub New(ByVal expression As String, ByVal options As RegexOptions)
m_Expression = expression
m_options = options
End Sub
Public ReadOnly Property Expression() As String
Get
Return m_Expression
End Get
End Property
Public ReadOnly Property Options() As RegexOptions
Get
Return m_Options
End Get
End Property
End Class
Public NotInheritable Class RuleTemplates
Public Shared ReadOnly Whitespace As New Rule("\s+")
Public Shared ReadOnly Identifier As New Rule("\w+")
Public Shared ReadOnly [String] As New Rule("""([^""]|"""")*""")
End Class
现在,当给一个声明为Rule
的变量赋值时,IDE会提供智能感知列表,列出可能的值来自于RuleTemplates
。
由于这是一个依赖于IDE的功能,很难展示它的使用方式,但我可以使用一张屏幕截图:
Completion list in action http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png
实际上,这个智能感知与使用Enum
时所得到的完全相同。
你有没有注意到 Like 比较运算符?
Dim b As Boolean = "file.txt" Like "*.txt"
更多信息请参考MSDN
Dim testCheck As Boolean
' The following statement returns True (does "F" satisfy "F"?)'
testCheck = "F" Like "F"
' The following statement returns False for Option Compare Binary'
' and True for Option Compare Text (does "F" satisfy "f"?)'
testCheck = "F" Like "f"
' The following statement returns False (does "F" satisfy "FFF"?)'
testCheck = "F" Like "FFF"
' The following statement returns True (does "aBBBa" have an "a" at the'
' beginning, an "a" at the end, and any number of characters in '
' between?)'
testCheck = "aBBBa" Like "a*a"
' The following statement returns True (does "F" occur in the set of'
' characters from "A" through "Z"?)'
testCheck = "F" Like "[A-Z]"
' The following statement returns False (does "F" NOT occur in the '
' set of characters from "A" through "Z"?)'
testCheck = "F" Like "[!A-Z]"
' The following statement returns True (does "a2a" begin and end with'
' an "a" and have any single-digit number in between?)'
testCheck = "a2a" Like "a#a"
' The following statement returns True (does "aM5b" begin with an "a",'
' followed by any character from the set "L" through "P", followed'
' by any single-digit number, and end with any character NOT in'
' the character set "c" through "e"?)'
testCheck = "aM5b" Like "a[L-P]#[!c-e]"
' The following statement returns True (does "BAT123khg" begin with a'
' "B", followed by any single character, followed by a "T", and end'
' with zero or more characters of any type?)'
testCheck = "BAT123khg" Like "B?T*"
' The following statement returns False (does "CAT123khg" begin with'
' a "B", followed by any single character, followed by a "T", and'
' end with zero or more characters of any type?)'
testCheck = "CAT123khg" Like "B?T*"
VB 通过 Import
别名提供了一种基本的 typedef
实现方式:
Imports S = System.String
Dim x As S = "Hello"
当与泛型类型一起使用时,这将更加有用:
Imports StringPair = System.Collections.Generic.KeyValuePair(Of String, String)
Imports Assert = xUnit.Assert
。 - wheelibin噢!别忘了XML字面量。
Dim contact2 = _
<contact>
<name>Patrick Hines</name>
<%= From p In phoneNumbers2 _
Select <phone type=<%= p.Type %>><%= p.Number %></phone> _
%>
</contact>
<string>This string contains "quotes" and it's OK.</string>.Value
(我发现在编写解析每个字段都带引号的 CSV 文件的测试时特别方便。手动转义所有这些引号将是非常麻烦的。) - Ryan Lundy初始化对象也在其中!
Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}
DirectCast
DirectCast
是一个神器。表面上看,它类似于 CType
运算符,将一个对象从一种类型转换为另一种类型。但是,它遵循一组更严格的规则。 CType
的实际行为通常是不透明的,无法明确执行哪种类型的转换。
DirectCast
仅支持两个不同的操作:
任何其他类型的转换都不起作用(例如尝试将 Integer
拆箱成 Double
),并会导致编译时/运行时错误(具体取决于情况和静态类型检查所能检测到的问题)。因此,尽可能使用 DirectCast
,因为这最能准确地表达我的意图:根据情况,我要么想拆箱已知类型的值,要么执行向上转型。就这样。
另一方面,使用 CType
会让代码的读者不确定程序员真正的意图,因为它会解析各种不同的操作,包括调用用户定义的代码。
为什么这是一个隐藏的特性?VB 团队发布了一份指南1,不鼓励使用 DirectCast
(尽管实际上它更快!),以使代码更加统一化。我认为这是一个不好的指南,应该被扭转:无论如何,都应该优先选择 DirectCast
而不是更通用的 CType
运算符。它可以使代码更加清晰易懂。另一方面,只有在确实需要时,即当需要调用缩窄的 CType
运算符时(参见运算符重载),才应该调用 CType
。
1) 我无法提供指南的链接,但我找到了VB团队的首席开发人员Paul Vick的看法:
在实际应用中,你几乎不会注意到其中的区别,因此最好选择更灵活的转换运算符,如CType,CInt等。
(Zack编辑:在这里了解更多: VB.NET中应该如何进行强制类型转换?)
TryCast
,因为我主要对普遍使用的CType
有意见。 - Konrad RudolphTryCast
仅适用于引用类型。 - Konrad RudolphIf
条件语句和合并运算符我不知道你会不会把它叫做隐藏的,但是 Iif([expression], [value if true], [value if false]) 函数可以算作一个。
它不是很隐藏,而是已弃用!VB 9有了更好的 If
运算符,它的功能类似于 C# 的条件运算符和合并运算符(取决于你想要什么):
Dim x = If(a = b, c, d)
Dim hello As String = Nothing
Dim y = If(hello, "World")
编辑以展示另一个例子:
这将适用于If()
,但会导致IIf()
抛出异常。
Dim x = If(b<>0,a/b,0)
:?
运算符是完全等价的,而不仅仅是简化版本。 - Konrad Rudolph这是一个不错的问题。VB.Net中的Select Case语句非常强大。
当然,也有标准的
Select Case Role
Case "Admin"
''//Do X
Case "Tester"
''//Do Y
Case "Developer"
''//Do Z
Case Else
''//Exception case
End Select
但这还不是全部...
你可以使用范围:
Select Case Amount
Case Is < 0
''//What!!
Case 0 To 15
Shipping = 2.0
Case 16 To 59
Shipping = 5.87
Case Is > 59
Shipping = 12.50
Case Else
Shipping = 9.99
End Select
还有更多...
你可以(尽管可能不是一个好主意)对多个变量进行布尔检查:
Select Case True
Case a = b
''//Do X
Case a = c
''//Do Y
Case b = c
''//Do Z
Case Else
''//Exception case
End Select
Select Case True
的问题在于它 看起来 好像会评估 每一个 Case
语句,并且运行每一个为真的代码。但实际上,它是逐个评估它们,并且只运行第一个为真的代码。如果要比较清晰地表达这种意思,If
语法则更好 (If...Else If...Else If...Else
)。 - Ryan Lundy最好且易用的CSV解析器:
Microsoft.VisualBasic.FileIO.TextFieldParser
通过添加对 Microsoft.VisualBasic 的引用,可以在任何其他 .Net 语言中使用,例如 C#