Скрытые особенности VB.NET?

Я довольно много узнал о просмотре Скрытых функций из С# и был удивлен, когда я не мог найти что-то аналогично для VB.NET.

Итак, каковы некоторые из его скрытых или менее известных функций?

Ответ 1

Предложение 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

Ответ 2

Пользовательский Enum s

Одной из настоящих скрытых функций VB является тег документации completionlist XML, который можно использовать для создания собственных типов Enum с расширенной функциональностью. Однако эта функция не работает на С#.

Один пример из моего последнего кода:

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

/EDIT:

Поскольку это функция, которая опирается на IDE, трудно показать, как это выглядит при ее использовании, но я просто использую скриншот:

Список завершений в действии http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

Фактически, IntelliSense на 100% идентичен тому, что вы получаете при использовании Enum.

Ответ 3

Вы заметили оператор сравнения 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*"

Ответ 4

Определения типов

VB знает примитивный тип typedef через Import псевдонимы:

Imports S = System.String

Dim x As S = "Hello"

Это более полезно при использовании в сочетании с общими типами:

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

Ответ 5

О! и не забывайте XML Literals.

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

Ответ 6

Инициализация объекта тоже там!

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

Ответ 7

DirectCast

DirectCast - это чудо. На поверхности он работает аналогично оператору CType в том смысле, что он преобразует объект из одного типа в другой. Однако он работает с гораздо более строгим набором правил. CType Поэтому фактическое поведение часто непрозрачно и совсем не видно, какое преобразование выполнено.

DirectCast поддерживает только две различные операции:

  • Разблокирование типа значения и
  • повышение уровня иерархии классов.

Любые другие действия не будут работать (например, при попытке удалить Integer в Double) и приведет к ошибке времени компиляции/времени выполнения (в зависимости от ситуации и того, что может быть обнаружено при проверке статического типа). Поэтому я использую DirectCast, когда это возможно, так как это лучше всего отражает мое намерение: в зависимости от ситуации я либо хочу, чтобы было освобождено значение известного типа или выполнялось повышение. Конец истории.

Использование CType, с другой стороны, оставляет читателя кода недоумевающим, что программист действительно намеревался, поскольку он разрешает все виды различных операций, включая вызов пользовательского кода.

Почему это скрытая функция? Команда VB опубликовала руководство 1 которое препятствует использованию DirectCast (даже если оно действительно быстрее!), Чтобы сделать код более однородным. Я утверждаю, что это неправильная рекомендация, которая должна быть отменена: По возможности пользуйтесь DirectCast более общим оператором CType. Это делает код намного понятнее. CType, с другой стороны, следует вызывать только в том случае, если это действительно предназначено, т.е. когда суживающий оператор CType (см. перегрузка оператора).


1) Я не могу придумать ссылку на руководство, но я нашел Пол Вик взял он (главный разработчик команды VB):

В реальном мире вы вряд ли заметите разницу, так что вы можете пойти с более гибкими операциями преобразования, такими как CType, CInt и т.д.


(EDIT от Zack: Подробнее здесь: Как мне сделать в VB.NET?)

Ответ 8

If условный и коалесцирующий оператор

Я не знаю, как бы вы это называли скрытым, но Iif ([expression], [value if true], [value if false]) Поскольку функция Object могла рассчитывать.

Это не столько скрыто, сколько устарело! VB 9 имеет оператор If, который намного лучше и работает точно так же, как С# условный и коалесцирующий оператор (в зависимости от того, что вы хотите):

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)

Ответ 9

Это хороший. Операция Select Case в VB.Net очень эффективна.

Конечно, есть стандартный

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

Ответ 10

Одна важная экономия времени, которую я использую все время, - это ключевое слово С:

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

Мне просто не нравится печатать больше, чем нужно!

Ответ 11

Лучший и простой парсер CSV:

Microsoft.VisualBasic.FileIO.TextFieldParser

Добавив ссылку на Microsoft.VisualBasic, это может быть использовано на любом другом языке .Net. С#

Ответ 13

Статические элементы в методах.

Например:

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 

Кроме того, это не то же самое, что просто объявить его как общий член класса; объекты, объявленные таким образом, также гарантируют поточность. В этом случае не имеет значения, так как выражение никогда не изменится, но есть и другие, где это возможно.

Ответ 14

В 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

Ответ 15

Пользовательские события

Хотя редко бывает полезно, обработка событий может быть сильно изменена:

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

Мне очень нравится "Мое" пространство имен, которое было представлено в Visual Basic 2005. Я - ярлык для нескольких групп информации и функциональности. Он обеспечивает быстрый и интуитивно понятный доступ к следующим типам информации:

  • My.Computer. Доступ к информации, связанной с компьютером, такой как файловая система, сеть, устройства, системная информация и т.д. Он обеспечивает доступ к ряду очень важных ресурсов, включая My.Computer. Сеть, My.Computer.FileSystem и My.Computer.Printers.
  • My.Application. Доступ к информации, связанной с конкретным приложением, например именем, версией, текущим каталогом и т.д.
  • My.User. Доступ к информации, связанной с текущим аутентифицированным пользователем.
  • My.Resources: доступ к ресурсам, используемым приложением, находящимся в файлах ресурсов строго типизированным образом.
  • My.Settings. Доступ к настройкам конфигурации приложения строго типизирован.

Ответ 17

Я только что нашел статью о "!" оператор, также известный как "оператор поиска словаря". Вот выдержка из статьи: http://panopticoncentral.net/articles/902.aspx

Техническое название! оператор является "оператором поиска словаря". словарь - это любой тип коллекции, который индексируется ключом, а не числа, точно так же, как записи в английском словаре индексируется по слову, который вы хотите значение. Наиболее распространенный пример типа словаря является 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"))

The! оператор может быть использован для поиска значения из любого типа словаря, который индексирует свои значения с помощью строк. идентификатор после! используется как ключ в операции поиска. Итак выше код мог бы быть написано:

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", потому что $is not в идентификаторах.) В VB6 и прежде, вы можете использовать скобки для вывести недопустимые идентификаторы (т. "Таблица! [AB $CD]" ), но когда мы начали используя скобки для поиска ключевых слов, мы потерял способность сделать это. В большинстве случаев, однако, это не слишком ограничение.

Чтобы получить действительно технический, x! y работает, если x имеет свойство по умолчанию, которое принимает String или Object в качестве параметра. В в этом случае x! y заменяется на x.DefaultProperty( "у" ). Интересный Обратите внимание на то, что существует специальная правило в лексической грамматике язык, чтобы все это работало.! символ также используется как тип символ на языке и тип персонажи едят перед операторами. Поэтому без специального правила x! Y будет сканироваться как "x! y" вместо "x! y". К счастью, поскольку нет место на языке, где два идентификаторы в строке действительны, мы просто ввел правило, что если следующий символ после! это начале идентификатора, мы считаем! быть оператором, а не типом характер.

Ответ 18

Это встроенное и определенное преимущество над С#. Возможность реализовать интерфейс Метод без использования того же имени.

Например:

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

End Sub

Ответ 19

Принуждение 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

См. Аргумент не изменяется с помощью вызова процедуры - Базовая переменная

Ответ 20

Передача параметров по имени и, следовательно, их переупорядочение

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

Ответ 21

Оператор Using является новым с VB 8, С# имел его с самого начала. Он вызывает автоматический выбор для вас.

например.

Using lockThis as New MyLocker(objToLock)

End Using

Ответ 22

Имена импорта также в значительной степени неизвестны:

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form

Ответ 23

Если вам нужно имя переменной для соответствия ключевому слову, заключите его в скобки. Не указано. однако лучше всего - но его можно использовать с умом.

например.

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

Ответ 24

Рассмотрим следующее объявление события

Public Event SomethingHappened As EventHandler

В С# вы можете проверить подписчиков на события, используя следующий синтаксис:

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

Ответ 25

Есть несколько ответов о XML-литералах, но не об этом конкретном случае:

Вы можете использовать литералы XML, чтобы заключать строковые литералы, которые в противном случае нужно было бы экранировать. Строковые литералы, содержащие, например, двойные кавычки.

Вместо этого:

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>, конечно, вы можете использовать любой тег, который вам нравится.)

Ответ 26

Вы можете иметь 2 строки кода только в одной строке. следовательно:

Dim x As New Something : x.CallAMethod

Ответ 27

DateTime может быть инициализирована путем сопоставления вашей даты С#

Dim independanceDay As DateTime = #7/4/1776#

Вы также можете использовать вывод типа вместе с этим синтаксисом

Dim independanceDay = #7/4/1776#

Это гораздо приятнее, чем использование конструктора

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

Ответ 28

Дополнительные параметры

Опционы намного проще, чем создавать новые перегрузки, например:

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

Ответ 29

Заголовок в VB.Net может быть достигнут старым VB6 fxn:

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

Ответ 30

Свойства с параметрами

Я занимаюсь программированием на С# и обнаружил недостающую особенность VB.Net, но не упоминался здесь.

Пример того, как это сделать (а также ограничение С#) можно увидеть по адресу: Использование типичных свойств 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