Answers:
该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
具有扩展功能的类似自己的类型。但是,此功能在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将提供IntelliSense可能的值列表RuleTemplates
。
由于此功能依赖于IDE,因此很难显示使用时的外观,但我只使用屏幕截图:
运行中的完成列表http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png
实际上,IntelliSense与使用时得到的100%相同Enum
。
friend
或使用与枚举相同的类(Rule
而不是)来防止这种情况RuleTemplate
。
您是否注意到“喜欢”比较运算符?
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知道一种原始的typedef
via Import
别名:
Imports S = System.String
Dim x As S = "Hello"
与泛型类型结合使用时,这将更为有用:
Imports StringPair = System.Collections.Generic.KeyValuePair(Of String, String)
Imports
它应该是。;-)以某种方式,将近整整一年都未发现此错误(并获得28次投票)。
Imports Assert = xUnit.Assert
哦! 并且不要忘记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文件,其中每一个领域是在引号测试时特别方便它将。不是一直好玩逃脱手工所有这些报价在我测试线。)
对象初始化也在那里!
Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}
DirectCast
DirectCast
是一个奇迹。从表面上看,它的作用类似于CType
操作符,它可以将对象从一种类型转换为另一种类型。但是,它按照更严格的规则进行工作。CType
因此,实际的行为通常是不透明的,完全不知道执行哪种转换。
DirectCast
仅支持两种不同的操作:
任何其他强制转换都将不起作用(例如,尝试对Integer
a 进行拆箱Double
),并会导致编译时/运行时错误(取决于情况以及通过静态类型检查可以检测到的内容)。因此DirectCast
,我会尽可能使用,因为这最能体现我的意图:根据情况,我要么想取消已知类型的值装箱,要么执行向上转换。故事结局。
CType
另一方面,使用,会使代码阅读者想知道程序员的真正意图,因为它可以解决各种不同的操作,包括调用用户定义的代码。
为什么这是隐藏功能?VB团队已发布了准则1,该准则不鼓励使用DirectCast
(即使实际上更快!)以使代码更加统一。我认为这是一个错误的指导原则,应该逆转:只要有可能,DirectCast
CType
就应该偏爱更通用的运算符。它使代码更加清晰。CType
另一方面,仅应在确实有此意图时调用,即应调用缩窄CType
运算符(请参阅运算符重载)时。
1)我无法找到该指南的链接,但我发现Paul Vick对此表示赞同(VB团队首席开发人员):
在现实世界中,您几乎不会注意到它们之间的区别,因此您最好使用更灵活的转换运算符,例如CType,CInt等。
(Zack编辑:在此处了解更多信息:如何在VB.NET中进行投射?)
TryCast
因为我主要是因为普遍使用来挑骨头CType
。
TryCast
根据文档,Enums是值类型,并且仅适用于引用类型。
If
条件合并运算符我不知道您怎么称呼它,但是Iif([expression],[value如果为true],[value如果为false])As Object函数可以计算在内。
它并没有被弃用那么多隐藏!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)
:?
运算符,而不仅仅是简化版本。
这是一个不错的。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
)。
我一直使用的一种主要的省时工具是With关键字:
With ReallyLongClassName
.Property1 = Value1
.Property2 = Value2
...
End With
我只是不喜欢输入超出要求的数字!
(编辑:此处了解更多信息:我应该始终使用AndAlso和OrElse运算符吗?)
方法中的静态成员。
例如:
Function CleanString(byval input As String) As String
Static pattern As New RegEx("...")
return pattern.Replace(input, "")
End Function
在上面的函数中,无论该函数被调用多少次,模式正则表达式都只会创建一次。
另一个用途是在周围保留一个“随机”实例:
Function GetNextRandom() As Integer
Static r As New Random(getSeed())
Return r.Next()
End Function
另外,这与简单地将其声明为类的Shared成员不同;这样声明的项也保证是线程安全的。在这种情况下,这无关紧要,因为表达式永远不会改变,但是在其他地方它可能会改变。
在vb中,这些运算符之间存在差异:
/
是Double
\
被Integer
忽略的余
Sub Main()
Dim x = 9 / 5
Dim y = 9 \ 5
Console.WriteLine("item x of '{0}' equals to {1}", x.GetType.FullName, x)
Console.WriteLine("item y of '{0}' equals to {1}", y.GetType.FullName, y)
'Results:
'item x of 'System.Double' equals to 1.8
'item y of 'System.Int32' equals to 1
End Sub
我真的很喜欢Visual Basic 2005中引入的“我的”命名空间。我是几组信息和功能的快捷方式。它提供了对以下类型信息的快速直观访问:
尽管很少有用,但是事件处理可以大量定制:
Public Class ApplePie
Private ReadOnly m_BakedEvent As New List(Of EventHandler)()
Custom Event Baked As EventHandler
AddHandler(ByVal value As EventHandler)
Console.WriteLine("Adding a new subscriber: {0}", value.Method)
m_BakedEvent.Add(value)
End AddHandler
RemoveHandler(ByVal value As EventHandler)
Console.WriteLine("Removing subscriber: {0}", value.Method)
m_BakedEvent.Remove(value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
Console.WriteLine("{0} is raising an event.", sender)
For Each ev In m_BakedEvent
ev.Invoke(sender, e)
Next
End RaiseEvent
End Event
Public Sub Bake()
''// 1. Add ingredients
''// 2. Stir
''// 3. Put into oven (heated, not pre-heated!)
''// 4. Bake
RaiseEvent Baked(Me, EventArgs.Empty)
''// 5. Digest
End Sub
End Class
然后可以通过以下方式对此进行测试:
Module Module1
Public Sub Foo(ByVal sender As Object, ByVal e As EventArgs)
Console.WriteLine("Hmm, freshly baked apple pie.")
End Sub
Sub Main()
Dim pie As New ApplePie()
AddHandler pie.Baked, AddressOf Foo
pie.Bake()
RemoveHandler pie.Baked, AddressOf Foo
End Sub
End Module
我刚刚找到一篇有关“!”的文章。运算符,也称为“字典查找运算符”。以下是该文章的摘录:http : //panopticoncentral.net/articles/902.aspx
的技术名称!运算符是“字典查找运算符”。词典是由键而不是数字索引的任何集合类型,就像英文词典中的条目由要定义的单词索引的方式一样。字典类型最常见的示例是System.Collections.Hashtable,它允许您将(键,值)对添加到哈希表中,然后使用键检索值。例如,以下代码将三个条目添加到哈希表中,并使用键“ Pork”查找其中之一。
Dim Table As Hashtable = New Hashtable
Table("Orange") = "A fruit"
Table("Broccoli") = "A vegetable"
Table("Pork") = "A meat"
Console.WriteLine(Table("Pork"))
!运算符可用于从任何使用字符串索引其值的字典类型中查找值。!后面的标识符 用作查找操作中的键。因此,上述代码可以改为:
Dim Table As Hashtable = New Hashtable
Table!Orange = "A fruit"
Table!Broccoli = "A vegetable"
Table!Pork = "A meat"
Console.WriteLine(Table!Pork)
第二个示例与第一个示例完全相同,但至少看起来更好,至少在我看来。我发现那里有很多地方!可以使用,尤其是在涉及XML和Web的情况下,那里只有成千上万个按字符串索引的集合。不幸的局限性在于!仍然必须是一个有效的标识符,因此,如果要用作键的字符串中包含一些无效的标识符字符,则不能使用!操作员。(例如,您不能说“ Table!AB $ CD = 5”,因为$在标识符中不合法。)在VB6及更高版本中,您可以使用方括号来转义无效的标识符(即“ Table![AB $ CD]“),但是当我们开始使用方括号对关键字进行转义时,我们就失去了这样做的能力。在多数情况下,
为了获得真正的技术性,如果x具有将String或Object作为参数的默认属性,则x!y可以工作。在这种情况下,x!y更改为x.DefaultProperty(“ y”)。一个有趣的旁注是,语言的词汇语法中有一个特殊的规则可以使所有这些工作。!字符也用作语言中的类型字符,并且类型字符在操作符之前被吃掉。因此,没有特殊规则,x!y将被扫描为“ x!y”而不是“ x!y”。幸运的是,由于该语言中没有位置连续两个标识符有效,因此我们引入了以下规则:是标识符的开始,我们考虑!成为操作员而不是键入字符。
这是内置的,并且比C#具有明显的优势。无需使用相同名称即可实现接口方法的能力。
如:
Public Sub GetISCSIAdmInfo(ByRef xDoc As System.Xml.XmlDocument) Implements IUnix.GetISCSIInfo
End Sub
强制ByVal
在VB中,如果将参数包装在额外的括号中,则可以覆盖方法的ByRef声明,并将其转换为ByVal。例如,以下代码产生4、5、5而不是4,5,6
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim R = 4
Trace.WriteLine(R)
Test(R)
Trace.WriteLine(R)
Test((R))
Trace.WriteLine(R)
End Sub
Private Sub Test(ByRef i As Integer)
i += 1
End Sub
按名称传递参数,然后重新排序
Sub MyFunc(Optional msg as String= "", Optional displayOrder As integer = 0)
'Do stuff
End function
用法:
Module Module1
Sub Main()
MyFunc() 'No params specified
End Sub
End Module
也可以使用“:=”参数规范以任何顺序调用:
MyFunc(displayOrder:=10, msg:="mystring")
导入别名在很大程度上也是未知的:
Import winf = System.Windows.Forms
''Later
Dim x as winf.Form
考虑以下事件声明
Public Event SomethingHappened As EventHandler
在C#中,可以使用以下语法检查事件订阅者:
if(SomethingHappened != null)
{
...
}
但是,VB.NET编译器不支持此功能。它实际上创建了一个隐藏的私有成员字段,该字段在IntelliSense中不可见:
If Not SomethingHappenedEvent Is Nothing OrElse SomethingHappenedEvent.GetInvocationList.Length = 0 Then
...
End If
更多信息:
http://jelle.druyts.net/2003/05/09/BehindTheScenesOfEventsInVBNET.aspx http://blogs.msdn.com/vbteam/archive/2009/09/25/testing-events-for-nothing-null-doug -rothaus.aspx
如果您需要一个变量名来与关键字匹配,请用方括号括起来。不可以。虽然是最佳做法-但可以明智地使用它。
例如
Class CodeException
Public [Error] as String
''...
End Class
''later
Dim e as new CodeException
e.Error = "Invalid Syntax"
例如,评论示例(@Pondidum):
Class Timer
Public Sub Start()
''...
End Sub
Public Sub [Stop]()
''...
End Sub
关于XML文字有几个答案,但是关于这种特定情况没有答案:
您可以使用XML Literals来封装否则将需要转义的字符串文字。例如,包含双引号的字符串文字。
代替这个:
Dim myString = _
"This string contains ""quotes"" and they're ugly."
你可以这样做:
Dim myString = _
<string>This string contains "quotes" and they're nice.</string>.Value
如果要测试CSV解析文字,这将特别有用:
Dim csvTestYuck = _
"""Smith"", ""Bob"", ""123 Anywhere St"", ""Los Angeles"", ""CA"""
Dim csvTestMuchBetter = _
<string>"Smith", "Bob", "123 Anywhere St", "Los Angeles", "CA"</string>.Value
(当然,您不必使用该<string>
标签;您可以使用任何喜欢的标签。)
<q>
就像Perl / Ruby中的用法一样,将是一个很好的标记。无论如何,这是一个很好的习惯用法。喜欢!
可选参数
可选选项比创建新的重载要容易得多,例如:
Function CloseTheSystem(Optional ByVal msg AS String = "Shutting down the system...")
Console.Writeline(msg)
''//do stuff
End Function
带参数的属性
我一直在做一些C#编程,发现了VB.Net所缺少的功能,但此处未提及。
有关如何执行此操作(以及c#限制)的示例,请参见:使用带有参数的C#中的典型get set属性。
我从该答案中摘录了代码:
Private Shared m_Dictionary As IDictionary(Of String, Object) = _
New Dictionary(Of String, Object)
Public Shared Property DictionaryElement(ByVal Key As String) As Object
Get
If m_Dictionary.ContainsKey(Key) Then
Return m_Dictionary(Key)
Else
Return [String].Empty
End If
End Get
Set(ByVal value As Object)
If m_Dictionary.ContainsKey(Key) Then
m_Dictionary(Key) = value
Else
m_Dictionary.Add(Key, value)
End If
End Set
End Property