Скрытые возможности VB.NET?

121

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

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

Теги:
hidden-features

64 ответа

134

Предложение 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
  • 9
    полезно, если вы хотите перехватить определенное исключение SQLException, скажем -2, которое, если я правильно помню, является сетевым тайм-аутом: поймать ex как sqlException, где ex.code = -2
  • 0
    Вот Это Да! Я просто прочитал это и сразу использовал его, чтобы упростить блок try / catch, который я только что написал на прошлой неделе. Я никогда не знал, что это существовало.
Показать ещё 2 комментария
86

Пользовательский 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.

  • 0
    Интересно - не могли бы вы показать пример того, как это выглядит, когда вы его потребляете?
  • 0
    Похоже, кто-то еще может создать свое собственное правило, вызвав конструктор Rule напрямую? Если да, и если вы хотите остановить это, можете ли вы объявить конструктор как «Друг» в вашей библиотеке?
Показать ещё 6 комментариев
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
    чего ждать? Это ново для меня! Хм, это чертовски лучше, чем альтернатива с VB.NET для работы со строками: D
  • 0
    .. !! Я этого не знал, хотя работал над несколькими проектами на vb.net! Интересная особенность ...
Показать ещё 7 комментариев
48

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

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

Imports S = System.String

Dim x As S = "Hello"

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

Imports StringPair = System.Collections.Generic.KeyValuePair(Of String, String)
  • 2
    Пожалуйста, покажите пример, слово Импорт не распознается в моей IDE.
  • 5
    Imports должен быть. ;-) Каким-то образом эта ошибка осталась незамеченной (и набрала 28 голосов) почти целый год.
Показать ещё 3 комментария
43

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

Dim contact2 = _
        <contact>
          <name>Patrick Hines</name>
          <%= From p In phoneNumbers2 _
            Select <phone type=<%= p.Type %>><%= p.Number %></phone> _
          %>
        </contact>
  • 0
    Это то, что я собирался сказать. Фактически, я использовал литералы XML для целей, для которых он не предназначен. Я использовал его для создания Javascript ... swortham.blogspot.com/2009/03/vb-2008.html
  • 9
    Помимо прочего, вы можете использовать XML-литералы, чтобы обойти некрасивые экранированные строки, например, когда вы используете строки, которые сами содержат двойные кавычки. Просто поместите строку в XML Literal и вызовите Value, как показано ниже: <string>This string contains "quotes" and it's OK.</string>.Value (я нашел это особенно удобным при написании тестов при разборе файлов CSV, где каждое поле был в кавычках. Это не было бы весело , чтобы избежать всех этих цитат вручную в моих тестовых строк.)
Показать ещё 2 комментария
39

DirectCast

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

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

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

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

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

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


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

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


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

  • 0
    Мне на самом деле нравится TryCast () немного лучше. Это не вызовет исключения, просто верните Nothing, если произойдет сбой приведения. Если вы ожидаете частого сбоя приведения, это будет быстрее, чем If TypeOf x Is T ... DirectCast (x, T) и, конечно, быстрее, чем перехват исключения, если сбой DirectCast завершится неудачей.
  • 6
    DirectCast () и TryCast () неоценимы при правильном использовании в паре. DirectCast () следует использовать, если ожидаемый объект всегда будет целевым типом (если это не так, вы получите ошибку, что хорошо, поскольку это непредвиденная ситуация). TryCast () следует использовать, если приводимый объект может быть целевого типа или нескольких целевых типов. Использование одного или другого исключительно приведет к дополнительным издержкам (если typeof x равен y, тогда directcast (x, y) неэффективен) или к избежанию допустимых ошибок (использование TryCast () для случаев, когда объект всегда должен быть целевым типом)
Показать ещё 4 комментария
39

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

Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}
  • 1
    Я не могу поверить, что они пошли с фигурными скобками. У нас уже есть оператор With ... они могли бы просто использовать этот синтаксис.
  • 2
    Я знаю, это сделано только для того, чтобы показать вам, что на дороге нет полицейского ... LOL JK
Показать ещё 1 комментарий
36

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)
  • 0
    Хорошо, я этого не знал! Я только вчера использовал IIF, так что я собираюсь вернуться к этому блоку кода.
  • 0
    Приятно знать. Впрочем, это не рекомендуется, если ваша работа ориентирована на среду 2.0.
Показать ещё 7 комментариев
33

Это хороший. Операция 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
  • 5
    На самом деле вы пропустили пару: a) использование «Select Case True» для проверки более чем одной переменной, b) использование формы «Case A, B, ...» и даже c) применение «:» к выровняйте оператор выполнения с условием условия (хотя многим это не нравится).
  • 6
    Пожалуйста, не используйте Select Case True. Просто используйте оператор If.
Показать ещё 2 комментария
32

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

Microsoft.VisualBasic.FileIO.TextFieldParser

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

  • 5
    +1 Странно, как люди C # бегут в FileHelpers, даже не задумываясь об этом. Я уверен, что FileHelpers отлично, но это внешняя зависимость.
  • 0
    @MarkJ Я полагаю, это из-за невежества
Показать ещё 2 комментария
32

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

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

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

  • 0
    Но это также создает некоторые скрытые ошибки, особенно когда у вас есть с внутри с
  • 2
    Я даже не знал, что вы можете поместить новый С в существующий. Это просто небрежно!
Показать ещё 7 комментариев
25
  • Логические операторы ANDAlso/OrElse

(EDIT: Подробнее здесь: Должен ли я всегда использовать операторы AndAlso и OrElse?)

  • 0
    Я бы не назвал это скрытым, если Contact IsNot Nothing AndAlso Contact.ContactId> 0 Тогда сделайте это, если вы будете использовать И у вас будет сгенерировано исключение.
24

В 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
  • 1
    Я научился этому нелегко, пытаясь найти иголку в миллионе строк кода. регулярное и целочисленное деление. хороший совет!
24

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

  • My.Computer. Доступ к информации, связанной с компьютером, такой как файловая система, сеть, устройства, системная информация и т.д. Он обеспечивает доступ к ряду очень важных ресурсов, включая My.Computer. Сеть, My.Computer.FileSystem и My.Computer.Printers.
  • My.Application. Доступ к информации, связанной с конкретным приложением, например именем, версией, текущим каталогом и т.д.
  • My.User. Доступ к информации, связанной с текущим аутентифицированным пользователем.
  • My.Resources: доступ к ресурсам, используемым приложением, находящимся в файлах ресурсов строго типизированным образом.
  • My.Settings. Доступ к настройкам конфигурации приложения строго типизирован.
  • 0
    Это просто замечательно, и каждый парень vb.net должен знать что-то в Моем пространстве имен, это так полезно.
  • 0
    Мой. * FTW :).
Показать ещё 4 комментария
24

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

Например:

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 

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

  • 1
    Одним из применений этого является сохранение счетчика, который будет увеличиваться при каждом вызове метода. Если переменная помечена как Static, она не будет повторно инициализирована при каждом вызове метода; он будет инициализирован только при первом вызове и после этого сохранит свое значение.
  • 0
    По этой причине статические члены класса называются «общими» в VB.NET.
Показать ещё 5 комментариев
22

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

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

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
  • 0
    кажется классным, но если мне когда-нибудь понадобится это, я думаю, что сделаю что-то не так ;-). Это просто кажется против принципа KISS.
  • 4
    Это действительно очень полезно, когда вы хотите убедиться, что каждый приемник получает событие, даже если один или несколько выдают исключение.
Показать ещё 2 комментария
20

Я только что нашел статью о "!" оператор, также известный как "оператор поиска словаря". Вот выдержка из статьи: 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". К счастью, поскольку нет место на языке, где два идентификаторы в строке действительны, мы просто ввел правило, что если следующий символ после! это начале идентификатора, мы считаем! быть оператором, а не типом характер.

  • 0
    Не знал, что это возможно в VB.NET, хотя выглядит плохо :)
  • 11
    Это одна из тех функций, которые я использовал, а потом намеренно забыл. Это экономит несколько нажатий клавиш, но мешает выделению моего кода и удобочитаемости. снова забыл прямо .... СЕЙЧАС
Показать ещё 6 комментариев
19

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

Например:

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

End Sub
  • 0
    Я уверен, что вы можете сделать что-то подобное в C #. В VB.NET его просто принудительно, а в C # его необязательно?
  • 5
    Не уверен, что это такая хорошая идея ... но это особенность :)
Показать ещё 5 комментариев
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

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

  • 6
    О, боже мой ... это замечательная особенность, хотя я не думаю, что знаю, что она делает, если бы я прочитал это в чужом коде. Если вам нужно прокомментировать его, просто чтобы узнать, что он делает, вы могли бы вместо этого сделать переменную выброса для передачи.
  • 7
    Это на самом деле побочный эффект от использования круглых скобок - скобки создают временное значение того, что внутри, даже если только один элемент. Этот эффект убил меня в vb6 - вызовы Sub не брали паренов, но я, пришедший из C, инстинктивно поместил парены в. 6.0 взорвался по нескольким параметрам, но для подпрограмм с одним параметром он успешно передал временное значение и ОТКАЗАЛСЯ в честь моего 'ByRef. Происходило примерно каждые 3 года, примерно в то время, когда я забыл последний инцидент.
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")
  • 0
    Вау, это супер круто! Я видел это при использовании веб-сервисов и т. Д., Но я не знал, что вы можете сделать это любым обычным способом.
  • 2
    Определенно очень удобный инструмент, когда вы сталкиваетесь с методом, который принимает слишком много аргументов. Я пытаюсь назвать каждый параметр и поместить имя: = значение в отдельной строке. Это намного более интуитивно понятно и чисто для методов, которые принимают> 5 (мое правило) параметров.
Показать ещё 4 комментария
15

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

например.

Using lockThis as New MyLocker(objToLock)

End Using
  • 23
    Стоит отметить (только потому, что я забыл хотя бы дважды), что вы можете иметь один оператор Using для переноса нескольких одноразовых объектов. Синтаксис «Использование objA в качестве нового объекта, objB в качестве нового объекта ....» Это намного чище, чем вложение нескольких операторов Using.
  • 0
    Определенно один из моих любимых.
14

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

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

  • 0
    Зачем тебе это делать? Я не могу представить вариант использования, когда вам нужно знать количество подписчиков на событие в VB.
  • 0
    В определенных обстоятельствах C # выдает исключение, если вы инициируете событие, и нет никаких обработчиков. VB.Net не будет. Отсюда и необходимость проверять.
Показать ещё 2 комментария
14

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

например.

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
  • 0
    черт, да брутто
  • 0
    Я думаю, что этот пример был бы лучше, если бы вы не использовали «Если» в качестве ключевого слова примера.
Показать ещё 4 комментария
14

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

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form
  • 1
    Я думаю, что у нас была та же идея.
  • 3
    @Boo - вот простой пример, когда псевдонимы импорта не являются злом. stackoverflow.com/questions/92869/...
Показать ещё 1 комментарий
13

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

  • 3
    <q> будет хорошим тегом, похожим на использование в Perl / Ruby. Во всяком случае, это довольно хорошая идиома. ЛАЙК!
  • 0
    Что за гениальная идея. Спасибо
12

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

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

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

Dim independanceDay = #7/4/1776#

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

Dim independanceDay as DateTime = New DateTime(1776, 7, 4)
  • 1
    Я действительно скучаю по этому в C #.
  • 0
    На самом деле, это работает очень хорошо с кавычками также.
Показать ещё 2 комментария
12

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

Dim x As New Something : x.CallAMethod
  • 0
    воу ... я думал, что это было возможно только с классом и наследством
  • 0
    Не забудьте Call (New Something).CallAMethod()
Показать ещё 2 комментария
11

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

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

Function CloseTheSystem(Optional ByVal msg AS String = "Shutting down the system...")
   Console.Writeline(msg)
   ''//do stuff
End Function
  • 0
    это так хорошо, что следующая версия C # получит его!
  • 1
    Я не знал, что C # собирался получить их. Они хороши, но вы должны быть осторожны, чтобы использовать их только тогда, когда вы уверены, что код не будет использоваться C #, поскольку он не поддерживает их. FxCop / Code Analysis скажет вам перегрузить метод вместо этого.
Показать ещё 2 комментария
9

Множество Stack/group с использованием операторов вместе:

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

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

  • 0
    Ваше соединение не открыто, поэтому оно не будет установлено ....
  • 0
    Должно быть лучше сейчас
Показать ещё 5 комментариев
9

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

Я занимаюсь программированием на С# и обнаружил недостающую особенность 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
  • 0
    Это интересно, но я не совсем уверен, где это было бы полезно. myObj.Something ("abc") больше похоже на доступ к функции, чем к свойству. Не уверен, что это тебя покупает.
  • 0
    Я ненавижу двусмысленность. Что это должно быть. Метод или свойство. Некоторые инструменты рефакторинга предлагают создавать и то и другое в определенных ситуациях, похоже, они даже не знают ...
9

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

StrConv(stringToTitleCase, VbStrConv.ProperCase,0) ''0 is localeID
  • 1
    это также в классе textinfo. не уверен, что это пространство имен. Вероятно, system.text
  • 0
    Вам лучше быть независимым от языка .net и использовать класс TextInfo Global для преобразования ToTitleCase. Если вам когда-нибудь понадобится конвертировать код в C #, у вас будет много маленьких неприятностей, требующих Microsoft.VisualBasic
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)

Это намного чище и без ошибок, затем вызывает функцию, подобную этой

DoSomething(1,true)
7

Уточненная обработка ошибок с использованием параметра

Обратите внимание на использование 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

7

Если вы никогда не знали о следующем, вы действительно не поверите, что это правда, это действительно то, что С# не хватает большого времени:

(Он называется 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

Взгляните на XML-литровые советы/рекомендации Бет Масси.

  • 1
    Покажите им один с заменами.
  • 0
    Я не знаю, так ли это называется. Я добавлю один.
Показать ещё 4 комментария
7

У вас может быть значение If в одной строке.

If True Then DoSomething()
  • 2
    а остальное тоже.
  • 1
    или если x = 0, то: Do0 (): ElseIf x = 1, затем Do1 (): еще Do3 (): EndIf
Показать ещё 4 комментария
7
  • Пространства имен дочерних объектов находятся в области после импорта родителя. Для примера, вместо того, чтобы импортировать System.IO или сказать System.IO.File, чтобы использовать класс File, вы можете просто сказать IO.File. Это простой пример: есть места, где эта функция действительно пригодится, а С# этого не делает.
  • 0
    Я просто ненавижу эту функцию, так как теряюсь, не глядя на пространство имен в начале файла ... но все равно +1!
6

В отличие от break на языках C в VB вы можете Exit или Continue блока, который хотите:

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
6

Здесь смешной, которого я не видел; Я знаю, что он работает в VS 2008, по крайней мере:

Если вы случайно закончили строку VB точкой с запятой, потому что вы делали слишком много С#, точка с запятой автоматически удаляется. На самом деле это невозможно (опять же, в VS 2008), чтобы случайно завершить линию VB точкой с запятой. Попробуйте!

(Это не идеально, если вы набираете точку с запятой на полпути через ваше окончательное имя класса, она не будет автозаполнять имя класса.)

5

При объявлении массива в vb.net всегда используйте синтаксис "0 to 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

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

  • 0
    Страшилки! ключевое слово "to" не пишется с большой буквы! ;)
  • 1
    Ключевые слова VB.NET нечувствительны к регистру. :) Не уверен, что это считается скрытой функцией.
Показать ещё 3 комментария
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
  • 0
    Какой смысл?
  • 0
    Учтите, что есть также ключевые слова Like From Error и другие, которые вы, возможно, захотите использовать, я знаю, что это редко, но всегда есть исключения.
Показать ещё 3 комментария
5
IIf(False, MsgBox("msg1"), MsgBox("msg2"))

Каков результат? две коробки сообщений!!!! Это происходит потому, что функция IIf оценивает оба параметра при достижении функции.

У VB есть новый оператор If (как оператор С#?:):

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

Покажет только второй msgbox.

в общем, я бы рекомендовал заменить все IIF в вашем коде vb, если вы не хотите, чтобы он обдумывал оба элемента:

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

вы можете быть уверены, что оба значения загружены.

5

Как и в ответе Parsa's, как оператор имеет лоты вещей, которые он может сопоставлять поверх простых подстановочных знаков. Я чуть не упал со стула, читая MSDN doco на нем:-)

5

Выберите Случай вместо нескольких операторов 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
  • 7
    Это мерзость.
  • 3
    В C # есть переключатель, и это мерзость
Показать ещё 6 комментариев
5

В VB8 и предыдущих версиях, если вы не указали какой-либо тип для введенной переменной, тип объекта был автоматически обнаружен. В VB9 (2008) Dim будет действовать как ключевое слово С# var, если для параметра Infer установлено значение On (по умолчанию)

  • 4
    ВСЕГДА устанавливайте Option Explicit. Вы можете использовать Tools-Options, чтобы вставить это автоматически во все новые исходные файлы.
  • 1
    Он автоматически устанавливается в свойствах проекта по умолчанию, если только вы не работаете с VB 6 или старше
Показать ещё 1 комментарий
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
  • 2
    +1 для хорошего взлома, но не очень полезного, поскольку .NET предоставляет ту же информацию, запрашивая GetType(T).IsValueType .
4

В отличие от С#, в 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

В то время как в С# это будет ошибка компилятора:

int x;
var y = x.ToString(); //Use of unassigned value
  • 0
    Нет, на самом деле вы не можете. Дим I как Integer не всегда 0.
  • 1
    @dwidel Можете ли вы предоставить какую-либо ссылку на базу, что вы сказали?
Показать ещё 1 комментарий
4

Ключевое слово MyClass предоставляет способ ссылаться на члены экземпляра класса, как первоначально реализовано, игнорируя переопределения производных классов.

4

может быть эта ссылка должна помочь

http://blogs.msdn.com/vbteam/archive/2007/11/20/hidden-gems-in-visual-basic-2008-amanda-silver.aspx

  • 0
    upvoted - хорошая ссылка
  • 0
    Круто, но в основном просто графический интерфейс.
4

Также важно помнить, что проекты VB.NET по умолчанию имеют корневое пространство имен, которое является частью свойств проектов. По умолчанию это корневое пространство имен будет иметь то же имя, что и проект. При использовании структуры блока пространства имен имена фактически добавляются к этому пространству имен корней. Например: если проект называется MyProject, мы можем объявить переменную как:

Private obj As MyProject.MyNamespace.MyClass

Чтобы изменить корневое пространство имен, используйте пункт меню "Проект → Свойства". Корневое пространство имен также может быть очищено, что означает, что все блоки пространства имен становятся корневым уровнем для кода, который они содержат.

  • 0
    Это укусило нас в нескольких случаях, когда мы добавляли дополнительные пространства имен внутри проекта. В некоторых случаях у нас есть ключевое слово «My» в одном из наших пространств имен; что делает поиск Ресурсов болью, пока вы не поймете, куда они были перемещены :)
3

VB также предлагает оператор OnError. Но в наши дни это не так много.

On Error Resume Next
' Or'
On Error GoTo someline

код >

  • 3
    +1: они должны убить этого.
  • 0
    @SungMeister, мне нравится, что исключения по электропитанию предоставляют и используют их в новом коде, но для (немногих) ситуаций, когда On Error Resume Next - правильная вещь, она гораздо менее загромождена, чем Try Catch для каждого оператора.
Показать ещё 2 комментария
3

Привязка пространств имен

Imports Lan = Langauge

Хотя он не уникален для VB.Net, он часто забывается при конфликтах пространства имен.

  • 0
    Можете ли вы сделать это и в переводе?
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 nullable, so has no value
        ElseIf unDate = dtValue.Value Then    'Unassigned variable
            '// still, it nullable for a reason, folks!
        Else
            .Value = CDate(dtValue.Value.ToShortDateString)
        End If
    End With
    Return aParm
End Function
  • 0
    В том же ключе обнуляемые числа!
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 (возможно, больше?) вещей, которые вы никогда не сможете сделать в С#:

  • Ручки Button1.Click - привязать обработчик к событию извне!
  • VB implicitness позволяет вам объявить первый параметр обработчика как expexted. в С# вы не можете адресовать делегат другому шаблону, даже ожидаемому типу.

Кроме того, в С# вы не можете использовать ожидаемые функции на объекте - на С# вы можете мечтать об этом (теперь они сделали динамическое ключевое слово, но оно далеко от VB). В С#, если вы напишете (новый объект()). Включено, вы получите сообщение об ошибке, что тип объекта не имеет метода "Включено". Теперь я не тот, кто порекомендует вас, если это будет безопасно или нет, информация предоставлена ​​КАК ЕСТЬ, сделайте сами по себе, по-прежнему оставайтесь на автобусе, иногда (например, при работе с объектами COM) это так хорошо. Я лично всегда пишу (отправитель As Button), когда ожидаемое значение, безусловно, является кнопкой.

На самом деле, кроме того: возьмите этот пример:

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
  • 3
    Ваши примеры работают только с Option Strict Off. А Option Strict Off - плохая вещь, потому что она приводит к ошибкам во время выполнения, если вы неправильно пишете имя членов с поздним связыванием, которые вы используете.
  • 1
    Строгое преимущество VB. У каждого свой вкус, у каждой вещи есть свои плюсы и минусы.
Показать ещё 1 комментарий
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

Пожалуйста, проголосуйте за эту функцию в Microsoft Connect.

  • 2
    Я думаю, что вы имеете в виду неявно
  • 0
    @Eric: Нет, явная реализация - это функция, доступная в C #, которая делает явно реализованный метод недоступным для экземпляров класса напрямую, и если вы хотите вызвать их, вы должны привести свой класс к типу интерфейса. Взгляните на msdn.microsoft.com/en-us/library/ms173157%28loband%29.aspx
Показать ещё 5 комментариев
2

Вы можете использовать REM, чтобы прокомментировать строку вместо ' , Не супер полезно, но помогает важным комментариям без использования "!!!!!!!" или что-то еще.

  • 5
    Обратите внимание, однако, что использование REM не рекомендуется. Команда VB рассматривает возможность полного удаления его из следующей версии. Таким образом, перспективный код лучше не использовать.
  • 1
    Правда, но они не говорили это с VB5?
Показать ещё 7 комментариев
2

Я не знаю, как спрятал бы ты его, но If может рассчитывать.

Он очень похож, в некотором смысле, на оператор ?: (тройной) или ?? на множестве C-подобных языков. Однако важно отметить, что он действительно оценивает все параметры, поэтому важно не передавать ничего, что может вызвать исключение (если вы этого не хотите) или что-либо, что может вызвать непреднамеренные побочные эффекты.

Использование:

Dim result = If(condition, valueWhenTrue, valueWhenFalse)
Dim value = If(obj, valueWhenObjNull)
  • 0
    Кроме того, тип возвращаемого значения - Object. Я использую свою собственную безопасную реализацию IIf (Of T).
  • 3
    В VB9 теперь есть оператор If, который является терновым оператором, как?: В C
Показать ещё 10 комментариев
1

Документация кода

''' <summary>
''' 
''' </summary>
''' <remarks></remarks>
Sub use_3Apostrophe()
End Sub
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
  • 0
    За исключением того, что, к сожалению, это не работает с коллекциями - попробуйте передать коллекцию в ByVal, а затем удалить элемент из нее в своей подпапке - вы обнаружите, что он также был удален из оригинала :(
  • 0
    Это работает с коллекцией тоже. Потому что, когда вы создаете коллекцию, вы не изменяете сам экземпляр, вы просто меняете его внутренние свойства. и если вы хотите увидеть его самостоятельно, попробуйте метод с параметром ByVal коллекции типов c, установите для него новую коллекцию внутри метода, и вы увидите, что аргумент не содержит вашу новую коллекцию вне область применения метода, в отличие от ByRef.
Показать ещё 1 комментарий
1

Когда-то основные пользователи не вводили никаких переменных. Они представили их, просто используя их. VB Option Explicit был введен только для того, чтобы вы не ошиблись при вводе какой-либо переменной из-за плохой типизации. Вы всегда можете переключить его на Off, испытать дни, которые мы работали с Basic.

  • 0
    Я никогда не включаю его, это добро называется VB !!! я!
1

Раньше я очень любил необязательные параметры функции, но теперь я использую их меньше, потому что мне нужно многократно перемещаться между С# и VB. Когда С# поддержит их? С++ и даже C имели их (вроде)!

  • 0
    Я никогда не был фанатом, но ваш ответ побудил меня немного покопаться в них и посмотреть, как они выглядят под капотом. Вы можете быть заинтересованы в [Как работают необязательные параметры?] [1] [1] stackoverflow.com/questions/104068/…
  • 2
    Необязательные параметры и именованные параметры будут в следующей версии C #.
Показать ещё 3 комментария
0

Дополнительные аргументы снова!

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

' Call
DoSmtg(,,"c argument")

DoSmtg(,"b argument")
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() также очень полезна, если вы выполняете какую-либо отладку (обратите внимание, что вы все равно можете поставить точку прерывания внутри функции или что-то еще, но вы не можете один шаг через эту функцию).

Кроме того, возможность помещать вещи в категории (например, "Данные" ) означает, что если вы хотите, чтобы свойство отображалось в окне инструментов свойств, это конкретное свойство будет отображаться в этой категории.

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

Ключевое слово Me

Ключевое слово "Я" уникально в VB.Net. Я знаю, что это довольно часто, но есть разница между "Я" и эквивалентом С# "this". Разница в "this" только для чтения, а "Me" - нет. Это полезно в конструкторах, где у вас есть экземпляр переменной, для которой вы хотите, чтобы переменная была сконструирована так же, как вы можете просто установить "Me = TheVariable", а не С#, где вам нужно будет скопировать каждое поле переменной вручную (что может быть ужасным, если есть много полей и склонность к ошибкам). Обходной путь С# состоял бы в том, чтобы выполнить назначение вне конструктора. Это означает, что теперь, если объект самосортирован для полного объекта, вам теперь нужна другая функция.

  • 2
    Нет, это чепуха. Me только для чтения, как this .
  • 1
    Да, это даст вам ошибку компиляции - 'Me' cannot be the target of an assignment
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню