VB.NET的隐藏功能?

时间:2008-09-19 14:07:02

标签: vb.net hidden-features

我已经学会了很多浏览Hidden Features of C#并且在我找不到的时候感到很惊讶 类似于VB.NET。

那么它的一些隐藏或鲜为人知的特征是什么?

64 个答案:

答案 0 :(得分:128)

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

答案 1 :(得分:82)

自定义Enum s

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会提供RuleTemplates中可能值的智能感知列表。

/编辑:

由于这是一个依赖于IDE的功能,因此在使用它时很难显示它的外观,但我只是使用屏幕截图:

Completion list in action http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

事实上,IntelliSense与使用Enum时的完全相同。

答案 2 :(得分:49)

您是否注意到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*"

答案 3 :(得分:48)

类型定义

VB通过typedef别名知道一种原始的Import

Imports S = System.String

Dim x As S = "Hello"

与泛型类型结合使用时更有用:

Imports StringPair = System.Collections.Generic.KeyValuePair(Of String, String)

答案 4 :(得分:45)

哦!不要忘记XML Literals

Dim contact2 = _
        <contact>
          <name>Patrick Hines</name>
          <%= From p In phoneNumbers2 _
            Select <phone type=<%= p.Type %>><%= p.Number %></phone> _
          %>
        </contact>

答案 5 :(得分:39)

对象初始化也在那里!

Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}

答案 6 :(得分:38)

DirectCast

DirectCast是一个奇迹。从表面上看,它的工作方式类似于CType运算符,因为它将对象从一种类型转换为另一种类型。但是,它的工作规则要严格得多。因此,CType的实际行为通常是不透明的,并且根本不明显执行哪种转换。

DirectCast仅支持两种不同的操作:

  • 取消装箱值类型,
  • 在类层次结构中向上转换。

任何其他强制转换都不起作用(例如,尝试将Integer拆箱到Double)并导致编译时/运行时错误(取决于情况以及静态可以检测到的内容)类型检查)。因此,我尽可能使用DirectCast,因为这最好地捕获了我的意图:根据情况,我要么取消已知类型的值或者执行向上转换。故事结束。

另一方面,使用CType让代码的读者想知道程序员真正想要的是什么,因为它解析为各种不同的操作,包括调用用户定义的代码。

为什么这是一个隐藏的功能? VB团队发布了一个指南 1 ,它不鼓励使用DirectCast(即使它实际上更快!),以使代码更加统一。我认为这是一个不好的指导方针,应该颠倒过来:尽可能支持DirectCast而不是更普通的CType运算符。它使代码更加清晰。另一方面,CType只有在确实需要时才会被调用,即应该调用缩小的CType运算符(参见operator overloading)。


1)我无法找到指南的链接,但我发现Paul Vick's take on it(VB团队的首席开发人员):

  

在现实世界中,你几乎不会注意到这种差异,所以你也可以选择CType,CInt等更灵活的转换运算符。


(Zack编辑:在此了解更多信息:How should I cast in VB.NET?

答案 7 :(得分:37)

If条件和合并运算符

  

我不知道你怎么称呼它,但是Iif([表达式],[值如果为真],[值如果为假])作为对象函数可以计算。

它不像已弃用那么隐藏! 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)

答案 8 :(得分:32)

这是一个很好的。 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

答案 9 :(得分:31)

最简单的CSV解析器:

Microsoft.VisualBasic.FileIO.TextFieldParser

通过添加对Microsoft.VisualBasic的引用,可以在任何其他.Net语言中使用,例如C#

答案 10 :(得分:31)

我一直使用的主要节省时间是使用关键字:

With ReallyLongClassName
    .Property1 = Value1
    .Property2 = Value2
    ...
End With

我只是不喜欢打字而不是我必须!

答案 11 :(得分:26)

  • AndAlso / OrElse逻辑运算符

(编辑:在此处了解详情:Should I always use the AndAlso and OrElse operators?

答案 12 :(得分:25)

方法中的静态成员。

例如:

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 

此外,这与简单地将其声明为该类的共享成员不同;以这种方式声明的项目也保证是线程安全的。在这种情况下并不重要,因为表达式永远不会改变,但还有其他可能的地方。

答案 13 :(得分:25)

在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

答案 14 :(得分:23)

我非常喜欢Visual Basic 2005中引入的“我的”命名空间我的是几组信息和功能的快捷方式。它提供对以下类型信息的快速直观访问:

  • My.Computer :访问与计算机相关的信息,如文件系统,网络,设备,系统信息等。它可以访问许多非常重要的资源,包括My.Computer。 Network,My.Computer.FileSystem和My.Computer.Printers。
  • My.Application :访问与特定应用程序相关的信息,例如名称,版本,当前目录等。
  • My.User :访问与当前经过身份验证的用户相关的信息。
  • My.Resources :以强类型方式访问驻留在资源文件中的应用程序所使用的资源。
  • My.Settings :以强类型方式访问应用程序的配置设置。

答案 15 :(得分:23)

自定义事件

虽然很少有用,但事件处理可以大量定制:

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

答案 16 :(得分:21)

我刚发现一篇文章谈论“!”运算符,也称为“字典查找运算符”。以下是文章摘录:http://panopticoncentral.net/articles/902.aspx

  

技术名称!操作者   是“字典查找运算符”。一个   dictionary是任何集合类型   由一个键而不是一个键索引   数字,就像那样的方式   英语词典中的条目是   用你想要的词索引   的定义。最常见的例子   字典类型是   System.Collections.Hashtable,其中   允许您添加(键,值)对   进入哈希表然后检索   使用键的值。例如,   以下代码添加了三个条目   到一个哈希表,看起来其中一个   使用关键“猪肉”。

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和网络,   哪里只有吨   由索引编制的集合   串。一个不幸的限制是   事后跟着!仍然   必须是有效的标识符,所以如果   要用作键的字符串   有一些无效的标识符字符   在它,你不能使用!运营商。   (例如,你不能说   “表!AB $ CD = 5”,因为$不是   标识符合法。)在VB6和   之前,您可以使用括号   转义无效标识符(即   “表![AB $ CD]”),但是当我们开始时   使用括号来转义关键字,我们   失去了做到这一点的能力。多数情况   但是,这并不是太多   限制。

     

要获得真正的技术,x!y可以工作   x有一个默认属性,需要一个   String或Object作为参数。在   那种情况,x!y变成了   x.DefaultProperty( “Y”)。一个有趣的   旁注是有一个特殊的   规则的词汇语法   语言使这一切都有效。的!   字符也用作类型   语言中的字符和类型   在操作员之前吃掉字符。   因此,没有特殊规则,x!y会   扫描为“x!y”而不是“x!   y“。幸运的是,因为没有   放在两个语言的地方   我们在一行中的标识符是有效的   刚刚介绍了规则,如果   之后的下一个角色!是个   我们考虑开始一个标识符   的!成为一个运营商,而不是一个类型   字符。

答案 17 :(得分:19)

这是内置的,并且比C#具有明显的优势。无需使用相同名称即可实现接口方法。

如:

Public Sub GetISCSIAdmInfo(ByRef xDoc As System.Xml.XmlDocument) Implements IUnix.GetISCSIInfo

End Sub

答案 18 :(得分:17)

强制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

请参阅Argument Not Being Modified by Procedure Call - Underlying Variable

答案 19 :(得分:16)

按名称传递参数,然后重新排序

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")

答案 20 :(得分:15)

自VB语句起,Using语句是新的,C#从一开始就拥有它。它会自动调用dispose。

E.g。

Using lockThis as New MyLocker(objToLock)

End Using

答案 21 :(得分:14)

考虑以下事件声明

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

答案 22 :(得分:14)

如果您需要一个变量名称来匹配关键字的名称,请用括号括起来。不是。虽然是最好的做法 - 但它可以明智地使用。

e.g。

Class CodeException
Public [Error] as String
''...
End Class

''later
Dim e as new CodeException
e.Error = "Invalid Syntax"

e.g。评论示例(@Pondidum):

Class Timer
Public Sub Start()
''...
End Sub

Public Sub [Stop]()
''...
End Sub

答案 23 :(得分:14)

导入别名在很大程度上也是未知的:

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form

答案 24 :(得分:13)

关于XML Literals有几个答案,但不是关于这个特定情况:

您可以使用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>标签;您可以使用您喜欢的任何标签。)

答案 25 :(得分:12)

可以使用#

围绕日期来初始化DateTime
Dim independanceDay As DateTime = #7/4/1776#

您还可以使用类型推断和此语法

Dim independanceDay = #7/4/1776#

这比使用构造函数

好很多
Dim independanceDay as DateTime = New DateTime(1776, 7, 4)

答案 26 :(得分:12)

您可以在一行中拥有2行代码。因此:

Dim x As New Something : x.CallAMethod

答案 27 :(得分:11)

可选参数

选项比创建新的重载要容易得多,例如:

Function CloseTheSystem(Optional ByVal msg AS String = "Shutting down the system...")
   Console.Writeline(msg)
   ''//do stuff
End Function

答案 28 :(得分:9)

带参数的属性

我一直在做一些C#编程,并发现了一个缺少VB.Net的功能,但这里没有提到。

如何执行此操作(以及c#限制)的示例可在以下位置查看:Using the typical get set properties in C#... with parameters

我摘录了该答案的代码:

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

答案 29 :(得分:9)

使用语句堆叠/分组多个:

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

公平地说,你也可以用C#来做。但是很多人都不知道这两种语言。

答案 30 :(得分:9)

VB.Net中的标题案例可以通过旧的VB6 fxn实现:

StrConv(stringToTitleCase, VbStrConv.ProperCase,0) ''0 is localeID

答案 31 :(得分:8)

我发现其中一个非常有用且有助于解决许多错误的功能是将参数显式传递给函数,尤其是在使用可选项时。

以下是一个例子:

Public Function DoSomething(byval x as integer, optional y as boolean=True, optional z as boolean=False)
' ......
End Function

然后你可以这样称呼它:

DoSomething(x:=1, y:=false)
DoSomething(x:=2, z:=true)
or
DoSomething(x:=3,y:=false,z:=true)

这样更干净,没有bug,然后调用这个函数

DoSomething(1,true)

答案 32 :(得分:7)

你可以在一行中有一个If。

If True Then DoSomething()

答案 33 :(得分:7)

使用When

进行精炼错误处理

请注意when

行中Catch ex As IO.FileLoadException When attempt < 3的使用情况
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

最近在VbRad

中查看

答案 34 :(得分:7)

如果你从来不知道以下内容,你真的不相信它是真的,这真的是C#缺乏时间的东西:

(它被称为XML文字)

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

看看Beth Massi的XML Literals Tips/Tricks

答案 35 :(得分:7)

  • 导入其父级后,子命名空间在范围内。例如,不必导入System.IO或者说System.IO.File来使用File类,你可以说IO.File。这是一个简单的例子:有些地方功能真的很方便,C#不会这样做。

答案 36 :(得分:6)

这是一个我从未见过的有趣的;我知道它在VS 2008中起作用,至少:

如果你不小心用分号结束你的VB行,因为你做了太多的C#,分号会被自动删除。实际上不可能(至少在VS 2008中)不小心用分号结束VB行。试试吧!

(这并不完美;如果您在最后一个班级名称的中途输入分号,则不会自动填写班级名称。)

答案 37 :(得分:6)

与VB中的C语言中的break不同,您可以ExitContinue您想要的块:

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

答案 38 :(得分:5)

在vb.net中声明数组时,始终使用“0到xx”语法。

Dim b(0 to 9) as byte 'Declares an array of 10 bytes

它清楚地表明了数组的范围。将它与等效的

进行比较
Dim b(9) as byte 'Declares another array of 10 bytes

即使你知道第二个例子由10个元素组成,它也感觉不太明显。而且我不记得我从程序员那里看到代码的次数,而不是写了

Dim b(10) as byte 'Declares another array of 10 bytes

这当然是完全错误的。因为b(10)创建一个11字节的数组。并且它很容易导致错误,因为它看起来对任何不知道要寻找什么的人都是正确的。

“0到xx”语法也适用于下面的

Dim b As Byte() = New Byte(0 To 9) {} 'Another way to create a 10 byte array
ReDim b(0 to 9) 'Assigns a new 10 byte array to b

通过使用完整语法,您还将向将来阅读您的代码的任何人展示您知道自己在做什么。

答案 39 :(得分:5)

如果用[和]

括起名称,可以对属性和变量名使用保留关键字
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

答案 40 :(得分:5)

IIf(False, MsgBox("msg1"), MsgBox("msg2"))

结果如何?两个消息框!!!! 发生这种情况时,IIf函数在到达函数时会计算两个参数。

VB有一个新的If运算符(就像C#?: operator):

If(False, MsgBox("msg1"), MsgBox("msg2"))

仅显示第二个msgbox。

一般情况下,我建议更换你的vb代码中的所有IIF,除非你想要它们两个项目:

Dim value = IIf(somthing, LoadAndGetValue1(), LoadAndGetValue2())

您可以确定两个值都已加载。

答案 41 :(得分:5)

Parsa's答案类似,like operator很多可以匹配的简单通配符。在阅读MSDN doco时,我几乎摔倒在椅子上:-)

答案 42 :(得分:5)

选择Case代替多个If / ElseIf / Else语句。

在此示例中假设简单的几何对象:

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

答案 43 :(得分:5)

在VB8和前面的版本中,如果没有为引入的变量指定任何类型,则会自动检测对象类型。在VB9(2008)中,如果Option Infer设置为On(默认情况下),Dim将像C#的var关键字一样

答案 44 :(得分:4)

同样重要的是要记住,默认情况下,VB.NET项目的根命名空间是项目属性的一部分。默认情况下,此根命名空间将与项目具有相同的名称。使用命名空间块结构时,名称实际上附加到该根命名空间。例如:如果项目名为MyProject,那么我们可以将变量声明为:

Private obj As MyProject.MyNamespace.MyClass

要更改根命名空间,请使用项目 - &gt;属性菜单选项。也可以清除根命名空间,这意味着所有命名空间块都成为它们包含的代码的根级别。

答案 45 :(得分:4)

Nothing关键字可以表示默认值(T)或null,具体取决于上下文。你可以利用它来制作一个非常有趣的方法:

'''<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

答案 46 :(得分:4)

与C#不同,在VB中,您可以依赖非可空项目的默认值:

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

答案 47 :(得分:4)

MyClass关键字提供了一种将类实例成员引用为最初实现的方法,忽略了任何派生类重写。

答案 48 :(得分:4)

答案 49 :(得分:3)

VB还提供了OnError语句。但是这些日子并没有多大用处。

On Error Resume Next
' Or'
On Error GoTo someline

On Error Resume Next ' Or' On Error GoTo someline

答案 50 :(得分:3)

混淆名称空间

Imports Lan = Langauge

虽然不是VB.Net独有的,但在遇到命名空间冲突时经常会忘记它。

答案 51 :(得分:2)

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

在这个片段中你有2个(可能更多?)你在C#中永远做不到的事情:

  1. 处理Button1.Click - 将处理程序附加到外部事件!
  2. VB的隐式允许您将处理程序的第一个参数声明为被驱逐类型。在C#中,你不能将委托给一个不同的模式,即使它是预期的类型。
  3. 此外,在C#中你不能在对象上使用预期的功能 - 在C#中你可以梦想它(现在他们制作了动态关键字,但它远离VB)。 在C#中,如果你要写(new object())。启用你会得到一个错误,类型对象没有方法'Enabled'。 现在,如果这是安全的话,我不是那个会推荐你的人,信息是按原样提供的,你自己做的,公共汽车,有时候(比如使用COM对象时)这是一件好事。 当预期值肯定是一个按钮时,我个人总是写(发送者为按钮)。

    实际上:以此为例:

    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
    

答案 52 :(得分:2)

不可能在VB中显式实现接口成员,但可以用不同的名称实现它们。

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

Please vote for this feature at Microsoft Connect

答案 53 :(得分:2)

您可以使用REM注释掉一行而不是' 。不是非常有用,但使用“!!!!!!!”帮助重要评论突出管他呢。

答案 54 :(得分:2)

可空的日期!这在您有数据进出数据库(在本例中为MSSQL Server)的情况下尤其有用。我有两个程序给我一个SmallDateTime参数,填充一个值。其中一个需要一个简单的旧日期并测试它是否有任何值,分配一个默认日期。另一个版本接受Nullable(Of Date),这样我就可以保持日期无价值,接受存储过程中的默认值

<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

答案 55 :(得分:2)

我不知道你怎么称呼它,但If运算符可以计算。

在某种程度上,它与许多类C语言中的?:(三元组)或??运算符非常相似。但是,重要的是要注意它确实评估了所有参数,因此重要的是不要传递任何可能导致异常的内容(除非你想要它)或任何可能导致意外副作用的东西。

用法:

Dim result = If(condition, valueWhenTrue, valueWhenFalse)
Dim value = If(obj, valueWhenObjNull)

答案 56 :(得分:1)

ByVal ByRef 关键字之间的差异:

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

答案 57 :(得分:1)

有一天,基本用户没有引入任何变量。他们只是通过使用它们来介绍它们。引入VB的Option Explicit只是为了确保你不会因输入错误而错误地引入任何变量。您可以随时将其关闭,体验我们使用Basic的日子。

答案 58 :(得分:1)

我曾经非常喜欢可选的函数参数,但我现在使用它们的次数较少,因为我必须经常在C#和VB之间来回走动。 C#何时会支持他们? C ++甚至C都有它们(一种)!

答案 59 :(得分:1)

代码文档

''' <summary>
''' 
''' </summary>
''' <remarks></remarks>
Sub use_3Apostrophe()
End Sub

答案 60 :(得分:0)

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

答案 61 :(得分:0)

方法的属性!例如,在设计时不应该可用的属性可以是1)对属性窗口隐藏,2)未序列化(特别是对于用户控件或从数据库加载的控件很烦):

<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

如果您进行任何调试,请加入DebuggerStepThrough() 非常有帮助(请注意,您仍然可以在函数或其他内容中设置断点,但您可以单步执行该功能。

此外,将事物分类(例如“数据”)的能力意味着,如果您希望该属性显示在属性工具窗口中,那么该特定属性将显示在那个类别中。

答案 62 :(得分:0)

再次选择参数!

Function DoSmtg(Optional a As string, b As Integer, c As String)
    'DoSmtg
End 

' Call
DoSmtg(,,"c argument")

DoSmtg(,"b argument")

答案 63 :(得分:-3)

我的关键字

“我”关键字在VB.Net中是唯一的。我知道它很常见,但“我”与C#等效“this”之间存在差异。不同之处在于“这个”是只读的而“我”不是。这在构造函数中是有价值的,在这种构造函数中,你有一个变量实例,你想要构造的变量已经相等,因为你可以设置“Me = TheVariable”而不是C#,你必须手动复制变量的每个字段(如果有很多字段并且容易出错,那就太可怕了。 C#的解决方法是在构造函数之外进行赋值。这意味着你现在如果对象是自我构建到一个完整的对象,你现在需要另一个函数。