VB.NET 的隐藏功能?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/102084/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 13:50:00  来源:igfitidea点击:

Hidden Features of VB.NET?

vb.nethidden-features

提问by Sean Gough

I have learned quite a bit browsing through Hidden Features of C#and was surprised when I couldn't find something similar for VB.NET.

我已经通过浏览C# 的隐藏功能学到了很多东西,当我找不到 VB.NET 类似的东西时,我感到很惊讶。

So what are some of its hidden or lesser known features?

那么它有哪些隐藏的或鲜为人知的功能呢?

回答by torial

The Exception Whenclause is largely unknown.

Exception When条款在很大程度上是未知的。

Consider this:

考虑一下:

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

回答by Konrad Rudolph

Custom Enums

自定义Enum小号

One of the real hiddenfeatures of VB is the completionlistXML documentation tag that can be used to create own Enum-like types with extended functionality. This feature doesn't work in C#, though.

VB真正隐藏的特性之一是completionlistXML 文档标记,可用于创建Enum具有扩展功能的类似自己的类型。但是,此功能在 C# 中不起作用。

One example from a recent code of mine:

我最近的代码中的一个例子:

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

Now, when assigning a value to a variable declared as Rule, the IDE offers an IntelliSense list of possible values from RuleTemplates.

现在,当为声明为 的变量赋值时Rule,IDE 会提供来自 的可能值的 IntelliSense 列表RuleTemplates

/EDIT:

/编辑:

Since this is a feature that relies on the IDE, it's hard to show how this looks when you use it but I'll just use a screenshot:

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

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

完成列表在行动 http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

In fact, the IntelliSense is 100% identical to what you get when using an Enum.

事实上,IntelliSense 与使用Enum.

回答by Parsa

Have you noticed the Like comparison operator?

您是否注意到 Like 比较运算符?

Dim b As Boolean = "file.txt" Like "*.txt"

Dim b As Boolean = "file.txt" Like "*.txt"

More from MSDN

更多来自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*"

回答by Konrad Rudolph

Typedefs

类型定义

VB knows a primitive kind of typedefvia Importaliases:

VB 知道一种原始的typedefviaImport别名:

Imports S = System.String

Dim x As S = "Hello"

This is more useful when used in conjunction with generic types:

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

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

回答by Nescio

Oh! and don't forget XML Literals.

哦!并且不要忘记XML 文字

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

回答by Nescio

Object initialization is in there too!

对象初始化也在那里!

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

回答by Konrad Rudolph

DirectCast

DirectCast

DirectCastis a marvel. On the surface, it works similar to the CTypeoperator in that it converts an object from one type into another. However, it works by a much stricter set of rules. CType's actual behaviour is therefore often opaque and it's not at all evident which kind of conversion is executed.

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

DirectCastonly supports two distinct operations:

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

  • Unboxing of a value type, and
  • upcasting in the class hierarchy.
  • 值类型的拆箱,以及
  • 在类层次结构中向上转换。

Any other cast will not work (e.g. trying to unbox an Integerto a Double) and will result in a compile time/runtime error (depending on the situation and what can be detected by static type checking). I therefore use DirectCastwhenever possible, as this captures my intent best: depending on the situation, I either want to unbox a value of known type or perform an upcast. End of story.

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

Using CType, on the other hand, leaves the reader of the code wondering what the programmer really intended because it resolves to all kinds of different operations, including calling user-defined code.

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

Why is this a hidden feature? The VB team has published a guideline1that discourages the use of DirectCast(even though it's actually faster!) in order to make the code more uniform. I argue that this is a bad guideline that should be reversed: Whenever possible, favour DirectCastover the more general CTypeoperator.It makes the code much clearer. CType, on the other hand, should only be called if this is indeed intended, i.e. when a narrowing CTypeoperator (cf. operator overloading) should be called.

为什么这是一个隐藏功能?VB 团队发布了一个准则1,该准则不鼓励使用DirectCast(即使它实际上更快!),以使代码更加统一。我认为这是一个错误的指导方针,应该颠倒过来:只要有可能,DirectCastCType就应该优先于更通用的操作符。它使代码更加清晰。CType,另一方面,只有在确实需要时才应调用,即在应调用缩小CType运算符(参见运算符重载)时。



1)I'm unable to come up with a link to the guideline but I've found Paul Vick's take on it(chief developer of the VB team):

1)我无法提供指向该指南的链接,但我找到了Paul Vick 对此的看法(VB 团队的首席开发人员):

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.

在现实世界中,您几乎不会注意到差异,因此您不妨使用更灵活的转换运算符,如 CType、CInt 等。



(EDIT by Zack: Learn more here: How should I cast in VB.NET?)

(扎克编辑:在此处了解更多信息:我应该如何在 VB.NET 中进行转换?

回答by Konrad Rudolph

Ifconditional and coalesce operator

If条件和合并运算符

I don't know how hidden you'd call it, but the Iif([expression],[value if true],[value if false]) As Object function could count.

我不知道你会怎么称呼它,但是 Iif([expression],[value if true],[value if false]) As Object 函数可以算数。

It's not so much hidden as deprecated! VB 9 has the Ifoperator which is much better and works exactly as C#'s conditional and coalesce operator (depending on what you want):

与其说是被弃用,不如说是隐藏!VB 9 有一个If更好的运算符,它的工作原理与 C# 的条件和合并运算符完全一样(取决于你想要什么):

Dim x = If(a = b, c, d)

Dim hello As String = Nothing
Dim y = If(hello, "World")


Edited to show another example:

编辑以显示另一个示例:

This will work with If(), but cause an exception with IIf()

这将适用于If(),但会导致异常IIf()

Dim x = If(b<>0,a/b,0)

回答by torial

This is a nice one. The Select Case statement within VB.Net is very powerful.

这是一个不错的。VB.Net 中的 Select Case 语句非常强大。

Sure there is the standard

肯定有标准

Select Case Role
  Case "Admin"
         ''//Do X
  Case "Tester"
         ''//Do Y
  Case "Developer"
         ''//Do Z
  Case Else
       ''//Exception case
End Select

But there is more...

但还有更多...

You can do ranges:

你可以做范围:

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

And even more...

甚至更多...

You can (although may not be a good idea) do boolean checks on multiple variables:

您可以(虽然可能不是一个好主意)对多个变量进行布尔检查:

Select Case True
 Case a = b
    ''//Do X
 Case a = c
    ''//Do Y
 Case b = c
    ''//Do Z
 Case Else
   ''//Exception case
 End Select

回答by Jasha87

One major time saver I use all the time is the Withkeyword:

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

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

I just don't like typing more than I have to!

我只是不喜欢打太多字!