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
One of the real 藏起来了 features of VB is the completionlist XML documentation tag that can be used to create own Enum-like types with extended functionality. This feature doesn't work in C#, though.
我最近的一个代码中的一个例子:
'
''' <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
为什么这是一个隐藏的特征?VB 团队发布了一个指南 1,该指南不鼓励使用 DirectCast(尽管它实际上更快!)为了使代码更加统一。我认为这是一个错误的指导方针,应该被颠倒过来: Whenever possible, favour ABC0 over the more general CType operator.它使代码更加清晰。另一方面,只有在确实需要调用 CType的情况下才应该调用 CType,也就是说,应该调用一个收缩的 CType操作符(参考 运算符重载)。
In the real world, you're hardly ever going to notice the difference, so you might as well go with the more flexible conversion operators like CType, CInt, etc.
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
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
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
It's not possible to Explicitly implement interface members in VB, but it's possible to implement them with a different name.
Interface I1
Sub Foo()
Sub TheFoo()
End Interface
Interface I2
Sub Foo()
Sub TheFoo()
End Interface
Class C
Implements I1, I2
Public Sub IAmFoo1() Implements I1.Foo
' Something happens here'
End Sub
Public Sub IAmFoo2() Implements I2.Foo
' Another thing happens here'
End Sub
Public Sub TheF() Implements I1.TheFoo, I2.TheFoo
' You shouldn't yell!'
End Sub
End Class
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*"
操作符的技术名称
是“字典查找操作符”
Dictionary 是指任何集合类型
是通过键而不是通过
number, just like the way that the
entries in an English dictionary are
由您想要的单词索引
最常见的例子
属于字典类型的是
系统,集合,哈希表,哪个
允许您添加(键,值)对
然后检索
值。例如,
下面的代码添加了三个条目
散列表,看起来就是其中之一
用“猪肉”这个键。
Dim Table As Hashtable = New Hashtable
Table("Orange") = "A fruit"
Table("Broccoli") = "A vegetable"
Table("Pork") = "A meat"
Console.WriteLine(Table("Pork"))
The ! operator can be used to look up
来自任何字典类型的值
使用字符串对其值进行索引
标识符之后,将! 用作
key in the lookup operation. So the
上面的代码本来可以是
写道:
Dim Table As Hashtable = New Hashtable
Table!Orange = "A fruit"
Table!Broccoli = "A vegetable"
Table!Pork = "A meat"
Console.WriteLine(Table!Pork)
第二个例子是
相当于第一个,但只是
looks a lot nicer, at least to my
eyes. I find that there are a lot of
可以使用! 的地方,尤其是
当涉及到 XML 和网络时,
那里有成吨的
索引的集合
string. One unfortunate limitation is
那个跟在后面的东西
必须是有效的标识符,所以如果
要用作键的字符串
有一些无效的标识符字符
在里面,你不能使用! 操作员。
(例如,你不能说
“ Table! AB $CD = 5”因为 $不是
在 VB6和
before, you could use brackets to
转义无效的标识符(即。
“桌子! [ AB $CD ]”) ,但当我们开始
使用括号转义关键字时,我们
失去了做到这一点的能力。在大多数情况下
然而,这并不是太多
一个限制。
更专业的说,x! y 在下列情况下工作
X 有一个默认属性,该属性接受
字符串或对象作为参数
在这种情况下,x! y 变成
x.DefaultProperty("y"). An interesting
边注是,有一个特别的
的词汇语法中的规则
语言使这一切工作!
字符也用作类型
字符的语言,和类型
字符在运算符之前被吃掉。
So without a special rule, x!y would
被扫描为“ x! y”而不是“ x!”!
幸运的是,由于没有
在语言中有两个地方
行中的标识符是有效的,则我们
只是引入了一个规则,如果
在! 之后的下一个字符是
开始一个标识符,我们认为
是操作符而不是类型
character.
Function GetToString(obj as SimpleGeomertyClass) as String
Select Case True
Case TypeOf obj is PointClass
Return String.Format("Point: Position = {0}", _
DirectCast(obj,Point).ToString)
Case TypeOf obj is LineClass
Dim Line = DirectCast(obj,LineClass)
Return String.Format("Line: StartPosition = {0}, EndPosition = {1}", _
Line.StartPoint.ToString,Line.EndPoint.ToString)
Case TypeOf obj is CircleClass
Dim Line = DirectCast(obj,CircleClass)
Return String.Format("Circle: CenterPosition = {0}, Radius = {1}", _
Circle.CenterPoint.ToString,Circle.Radius)
Case Else
Return String.Format("Unhandled Type {0}",TypeName(obj))
End Select
End Function
Dim sql As String = "StoredProcedureName"
Using cn As SqlConnection = getOpenConnection(), _
cmd As New SqlCommand(sql, cn), _
rdr As SqlDataReader = cmd.ExecuteReader()
While rdr.Read()
''// Do Something
End While
End Using
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
Imports <xmlns:xs="System">
Module Module1
Sub Main()
Dim xml =
<root>
<customer id="345">
<name>John</name>
<age>17</age>
</customer>
<customer id="365">
<name>Doe</name>
<age>99</age>
</customer>
</root>
Dim id = 1
Dim name = "Beth"
DoIt(
<param>
<customer>
<id><%= id %></id>
<name><%= name %></name>
</customer>
</param>
)
Dim names = xml...<name>
For Each n In names
Console.WriteLine(n.Value)
Next
For Each customer In xml.<customer>
Console.WriteLine("{0}: {1}", customer.@id, customer.<age>.Value)
Next
Console.Read()
End Sub
Private Sub CreateClass()
Dim CustomerSchema =
XDocument.Load(CurDir() & "\customer.xsd")
Dim fields =
From field In CustomerSchema...<xs:element>
Where field.@type IsNot Nothing
Select
Name = field.@name,
Type = field.@type
Dim customer =
<customer> Public Class Customer
<%= From field In fields Select <f>
Private m_<%= field.Name %> As <%= GetVBPropType(field.Type) %></f>.Value %>
<%= From field In fields Select <p>
Public Property <%= field.Name %> As <%= GetVBPropType(field.Type) %>
Get
Return m_<%= field.Name %>
End Get
Set(ByVal value As <%= GetVBPropType(field.Type) %>)
m_<%= field.Name %> = value
End Set
End Property</p>.Value %>
End Class</customer>
My.Computer.FileSystem.WriteAllText("Customer.vb",
customer.Value,
False,
System.Text.Encoding.ASCII)
End Sub
Private Function GetVBPropType(ByVal xmlType As String) As String
Select Case xmlType
Case "xs:string"
Return "String"
Case "xs:int"
Return "Integer"
Case "xs:decimal"
Return "Decimal"
Case "xs:boolean"
Return "Boolean"
Case "xs:dateTime", "xs:date"
Return "Date"
Case Else
Return "'TODO: Define Type"
End Select
End Function
Private Sub DoIt(ByVal param As XElement)
Dim customers =
From customer In param...<customer>
Select New Customer With
{
.ID = customer.<id>.Value,
.FirstName = customer.<name>.Value
}
For Each c In customers
Console.WriteLine(c.ToString())
Next
End Sub
Private Class Customer
Public ID As Integer
Public FirstName As String
Public Overrides Function ToString() As String
Return <string>
ID : <%= Me.ID %>
Name : <%= Me.FirstName %>
</string>.Value
End Function
End Class
End Module
'Results:
ID : 1
Name : Beth
John
Doe
345: 17
365: 99
Sub Main()
Select Case "value to check"
'Check for multiple items at once:'
Case "a", "b", "asdf"
Console.WriteLine("Nope...")
Case "value to check"
Console.WriteLine("Oh yeah! thass what im talkin about!")
Case Else
Console.WriteLine("Nah :'(")
End Select
Dim jonny = False
Dim charlie = True
Dim values = New String() {"asdff", "asdfasdf"}
Select Case "asdfasdf"
'You can perform boolean checks that has nothing to do with your var.,
'not that I would recommend that, but it exists.'
Case values.Contains("ddddddddddddddddddddddd")
Case True
Case "No sense"
Case Else
End Select
Dim x = 56
Select Case x
Case Is > 56
Case Is <= 5
Case Is <> 45
Case Else
End Select
End Sub
Sub Main()
'Auto assigned to def value'
Dim i As Integer '0'
Dim dt As DateTime '#12:00:00 AM#'
Dim a As Date '#12:00:00 AM#'
Dim b As Boolean 'False'
Dim s = i.ToString 'valid
End Sub
而在 C # 中,这将是一个编译器错误:
int x;
var y = x.ToString(); //Use of unassigned value
Public Class Item
Private Value As Integer
Public Sub New(ByVal value As Integer)
Me.Value = value
End Sub
Public ReadOnly Property [String]() As String
Get
Return Value
End Get
End Property
Public ReadOnly Property [Integer]() As Integer
Get
Return Value
End Get
End Property
Public ReadOnly Property [Boolean]() As Boolean
Get
Return Value
End Get
End Property
End Class
'Real examples:
Public Class PropertyException : Inherits Exception
Public Sub New(ByVal [property] As String)
Me.Property = [property]
End Sub
Private m_Property As String
Public Property [Property]() As String
Get
Return m_Property
End Get
Set(ByVal value As String)
m_Property = value
End Set
End Property
End Class
Public Enum LoginLevel
[Public] = 0
Account = 1
Admin = 2
[Default] = Account
End Enum
Private Sub Button1_Click(ByVal sender As Button, ByVal e As System.EventArgs)
Handles Button1.Click
sender.Enabled = True
DisableButton(sender)
End Sub
Private Sub Disable(button As Object)
button.Enabled = false
End Sub
在这个代码片段中,有两个(也许更多?)你在 C # 中永远不可能做到的事情:
处理 Button1.Click-在外部将处理程序附加到事件!
VB 的隐式允许您将处理程序的第一个参数声明为期望类型。在 C # 中,您不能将委托定位到不同的模式,即使它是预期的类型。
另外,在 C # 中,你不能在对象上使用期望的功能——在 C # 中,你可以梦想它(现在他们创建了 Dynamic 关键字,但是它远离 VB)。
在 C # 中,如果你写(new object ())。“启用”将得到一个错误,即类型对象没有“启用”方法。
Now, I am not the one who will recommend you if this is safe or not, the info is provided AS IS, do on your own, bus still, sometimes (like when working with COM objects) this is such a good thing.
当期望值肯定是一个按钮时,我个人总是写(发送方为按钮)。
实际上,举个例子:
Private Sub control_Click(ByVal sender As Control, ByVal e As System.EventArgs)
Handles TextBox1.Click, CheckBox1.Click, Button1.Click
sender.Text = "Got it?..."
End Sub
Module Module1
Sub Main()
Dim str1 = "initial"
Dim str2 = "initial"
DoByVal(str1)
DoByRef(str2)
Console.WriteLine(str1)
Console.WriteLine(str2)
End Sub
Sub DoByVal(ByVal str As String)
str = "value 1"
End Sub
Sub DoByRef(ByRef str As String)
str = "value 2"
End Sub
End Module
'Results:
'initial
'value 2
'''<summary>Returns true for reference types, false for struct types.</summary>'
Public Function IsReferenceType(Of T)() As Boolean
Return DirectCast(Nothing, T) Is Nothing
End Function
注意 Catch ex As IO.FileLoadException When attempt < 3行中使用的 when
Do
Dim attempt As Integer
Try
''// something that might cause an error.
Catch ex As IO.FileLoadException When attempt < 3
If MsgBox("do again?", MsgBoxStyle.YesNo) = MsgBoxResult.No Then
Exit Do
End If
Catch ex As Exception
''// if any other error type occurs or the attempts are too many
MsgBox(ex.Message)
Exit Do
End Try
''// increment the attempt counter.
attempt += 1
Loop
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
<System.ComponentModel.Browsable(False), _
System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden), _
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always), _
System.ComponentModel.Category("Data")> _
Public Property AUX_ID() As String
<System.Diagnostics.DebuggerStepThrough()> _
Get
Return mAUX_ID
End Get
<System.Diagnostics.DebuggerStepThrough()> _
Set(ByVal value As String)
mAUX_ID = value
End Set
End Property
Also, the ability to put things in categories (e.g., "Data") means that, if you 做 want the property to show up in the properties tool-window, that particular property will show up in that category.
<System.Diagnostics.DebuggerStepThrough> _
Protected Function GP(ByVal strName As String, ByVal dtValue As Date) As SqlParameter
Dim aParm As SqlParameter = New SqlParameter
Dim unDate As Date
With aParm
.ParameterName = strName
.Direction = ParameterDirection.Input
.SqlDbType = SqlDbType.SmallDateTime
If unDate = dtValue Then 'Unassigned variable
.Value = "1/1/1900 12:00:00 AM" 'give it a default which is accepted by smalldatetime
Else
.Value = CDate(dtValue.ToShortDateString)
End If
End With
Return aParm
End Function
<System.Diagnostics.DebuggerStepThrough()> _
Protected Function GP(ByVal strName As String, ByVal dtValue As Nullable(Of Date)) As SqlParameter
Dim aParm As SqlParameter = New SqlParameter
Dim unDate As Date
With aParm
.ParameterName = strName
.Direction = ParameterDirection.Input
.SqlDbType = SqlDbType.SmallDateTime
If dtValue.HasValue = False Then
'// it's nullable, so has no value
ElseIf unDate = dtValue.Value Then 'Unassigned variable
'// still, it's nullable for a reason, folks!
Else
.Value = CDate(dtValue.Value.ToShortDateString)
End If
End With
Return aParm
End Function
For i As Integer = 0 To 100
While True
Exit While
Select Case i
Case 1
Exit Select
Case 2
Exit For
Case 3
Exit While
Case Else
Exit Sub
End Select
Continue For
End While
Next