Приховані особливості VB.NET?


121

Я навчився трохи переглядати приховані особливості C # і був здивований, коли не зміг знайти щось подібне для VB.NET.

Отже, які є деякі його приховані чи менш відомі особливості?

Відповіді:


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

9
корисно, якщо ви хочете впіймати певний SQLException, скажіть, -2, якщо я правильно пам’ятаю, це тайм-аут мережі: Catch ex як sqlException, коли ex.code = -2
Pondidum

Оце Так! Я просто прочитав це і ставлю його негайно використовувати для спрощення блоку спробу / лову, про який я писав минулого тижня. Я ніколи нового цього не існував.
Джон М Гант

1
+1 І ось, де в блозі команди NET CLR пояснюється, чому корисні фільтри винятків blogs.msdn.com/clrteam/archive/2009/02/05/…
MarkJ

5
Це не тільки приховано, але воно також недоступне в C #.
Чесо

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 пропонує список можливих значень IntelliSense зRuleTemplates .

/ EDIT:

Оскільки це функція, яка покладається на IDE, важко показати, як це виглядає, коли ви його використовуєте, але я просто використаю скріншот:

Список заповнень у дії http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

Насправді IntelliSense на 100% ідентичний тому, що ви отримуєте під час використання Enum.


Цікаво - ви могли б показати приклад того, як це виглядає, коли ви його споживаєте?
Брайан Маккей,

Схоже, хтось все-таки може створити своє правило, зателефонувавши конструктору Правил безпосередньо? Якщо так, і якщо ви хочете це зупинити, чи могли б ви оголосити конструктора як "Друга" у вашій бібліотеці?
Джоел Куехорн

Джоель, у своєму прикладі коду я навмисно не заборонив цього. Швидше пропоную користувачеві деякі загальні правила і дозволяю створювати власні, спеціалізовані правила. Звичайно, ви можете запобігти цьому, позначивши конструктор як friendабо використовуючи той же клас, що і enum: Ruleзамість RuleTemplate.
Конрад Рудольф

є десь зі списком прихованих корисних атрибутів? ця обличчя здається неймовірною, але я ще не впевнений, де я б її застосував, або якщо вона могла б вирішити первинний захват у деяких випадках, не маючи можливості мати загальне обмеження на перерахунки.
Маслоу

@Maslow: тут не задіяний атрибут. Це коментар xml.
Joel Coehoorn

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
STW

.. !! Я цього не знав, хоча працював над кількома проектами vb.net! Цікава особливість ...
Meta-Knight

woooooooooooooooooooooooow! Дякую! це дивовижно! це працює і в ELinq, і в DLinq? що з XLinq?
Шиммі Вайцхандлер

@dotjoe Хм? У цих глобусах нічого "ледачого".
Джош Лі

Як це відбувається, що відбувається під кришкою? Це синонім бібліотеки reg ex?
brumScouse

48

Typedefs

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

Imports S = System.String

Dim x As S = "Hello"

Це корисніше при використанні спільно з загальними типами:

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

2
будь ласка, покажіть приклад: слово Імпорт не розпізнається в моєму IDE.
Shimmy Weitzhandler

5
Importsвона повинна бути. ;-) Так чи інакше, ця помилка майже цілий рік не виявилась (і отримала 28 оновлень).
Конрад Рудольф

Мені завжди було цікаво, як я можу зробити новий "тип" із за замовчуванням для загального! Класно!
ейдилон

3
Імпорт, імпорт, імпорт, що завгодно! Шееш, ти думаєш, ми читали ці пости, перш ніж ми їх оскаржили!
MarkJ

Чудовий варіант використання xunit у тестах візуальної студії, тобтоImports Assert = xUnit.Assert
wheelibin

45

Ой! і не забувайте XML Literals .

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

Ось що я збирався сказати. Насправді я використовував XML-літерали для тієї мети, в якій він не був призначений. Я використовував його для створення Javascript ... swortham.blogspot.com/2009/03/vb-2008.html
Стів

9
Крім усього іншого, ви можете використовувати XML Literals, щоб уникнути появи некрасивих рядків, наприклад, коли ви використовуєте рядки, які самі містять подвійні лапки. Просто помістіть рядок всередині XML буквального і викликати значення, як це: <string>This string contains "quotes" and it's OK.</string>.Value (я знайшов це особливо зручно при написанні тестів на розборі CSV файлів , де кожне поле було в лапках було б. Чи не було весело , щоб уникнути всіх цих цитат вручну в моєму тестові лінії.)
Райан Лунді

2
@Kyralessa: +1, чудовий коментар. Насправді це також чудовий спосіб вказати багаторядкові рядки (обіймає оператори SQL тощо).
Хайнзі

Вбудований XML - одна з найгірших функцій VB.NET, яка коли-небудь була задумана. Не обгрунтований факт.
Грант Томас

39

Ініціалізація об’єктів теж є!

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

1
Не можу повірити, що вони пішли з фігурними дужками. У нас уже є твердження With .. вони могли просто використати цей синтаксис.
Сем Топор

2
Я знаю, це зроблено просто для того, щоб показати вам, що в дорозі немає поліцейського ... lol JK
Shimmy Weitzhandler

4
Це відбувається, коли всі автори-компілятори по суті є самими програмістами C / C ++. Вони продовжують ковзати синтаксис C іншими мовами, оскільки не можуть уявити, що б щось було кращим.
RBarryYoung,

38

DirectCast

DirectCast- диво. На поверхні він працює аналогічно CTypeоператору тим, що перетворює об’єкт з одного типу в інший. Однак це працює за набагато суворішим набором правил. CTypeТому фактична поведінка часто непрозора, і зовсім не видно, який вид конверсії здійснюється.

DirectCast підтримує лише дві різні операції:

  • Розв’язування типу значення та
  • оновлення в ієрархії класів.

Будь-яка інша трансляція не працюватиме (наприклад, спроба розблокувати Integerвід a до a Double) і призведе до помилки часу компіляції / часу виконання (залежно від ситуації та того, що може бути виявлено статичною перевіркою типу) Тому я використовуюDirectCast коли це можливо, оскільки це найкраще фіксує мої наміри: залежно від ситуації я хочу розблокувати значення відомого типу або здійснити оновлення. Кінець історії.

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

Чому це прихована особливість? Команда VB опублікувала керівництво 1, яке відмовляє від використання DirectCast(хоча це насправді швидше!), Щоб зробити код більш рівномірним. Я стверджую, що це погана настанова, яку слід змінити: Коли це можливо, надайте перевагу DirectCastбільш загальному CTypeоператору. Це робить код набагато зрозумілішим. CTypeз іншого боку, слід викликати лише тоді, коли це дійсно призначено, тобто коли слід викликати CTypeоператора звуження (пор. перевантаження оператора ).


1) Я не можу створити посилання на керівний принцип, але я виявив, що Пол Вік прийняв його (головний розробник команди VB):

У реальному світі ви навряд чи коли-небудь помітите різницю, тому ви можете також перейти з більш гнучкими операторами перетворення, такими як CType, CInt тощо.


(EDIT by Zack: Докладніше тут: Як я можу подати участь у VB.NET? )


Мені справді подобається TryCast () трохи краще. Виняток не кине, просто поверніть Ніщо, якщо виступ не вдасться. Якщо ви очікуєте, що випадок часто виходить з ладу, це швидше, ніж If TypeOf x Is T ... DirectCast (x, T), і, звичайно, швидше, ніж ловити виняток, якщо DirectCast не вдасться.
Боб Кінг

6
DirectCast () та TryCast () є безцінними при правильному використанні в якості пари. DirectCast () слід використовувати, якщо очікуваний об’єкт завжди очікується типовим типом (якщо це не помилка, добре, оскільки це несподівана ситуація). TryCast () слід використовувати, якщо об'єкт, який викидається, може бути цільового типу або декількох цільових типів. Використання виключно одного або іншого призведе до додаткових накладних витрат (якщо typeof x y, то directcast (x, y) є неефективним), або до уникнення допустимих помилок (використання TryCast () для випадків, коли об'єкт завжди повинен бути цільовим типом)
STW

Yoooder: 100% вірно. Прикро, що я не згадував TryCastтоді, оскільки в основному мав кості відбирати під час поширеного використання CType.
Конрад Рудольф

@Maslow: звичайно, це не так, оскільки Enums - це типові значення і TryCastпрацює лише на типи посилань, відповідно до документації.
Конрад Рудольф

+1: Хе. Я повинен визнати, я просто прочитав це і подумав: "Так, DirectCast, як я забув про це?" А потім я використав це в моєму наступному рядку коду (оскільки мені дуже не подобається CType).
RBarryYoung

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)

Добре, я цього не знав! Я щойно використовував IIF вчора, тому збираюся переглянути цей блок коду.
Шон Гоф

4
Скажіть VS 2005, що. Не всі з нас приступають до роботи з останніми та найбільшими.
Сем Ервін

3
@ Соло, нісенітниця. Цей метод є 100% безпечним, і він повертає об'єкт того ж типу, що і його (другий та третій) аргументи. Крім того, між аргументами має бути розширення перетворення, інакше буде помилка компіляції, оскільки типи не збігаються.
Конрад Рудольф

1
Так, його IIf (), який не є безпечним для типу
Pondidum

2
@ Br.Bill Насправді це повністю еквівалентно:? оператору C та Perl , це не просто спрощена версія.
Конрад Рудольф

32

Це приємне. Заява 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
Власне, ви пропустили пару: вирівняйте оператор виконання застережним умовою (хоча багатьом це не подобається).
RBarryYoung,

6
Не використовуйте Select Case True. Просто використовуйте оператор If.
Райан Лунді

4
Я вважаю Select Case True набагато простішим для читання, ніж гігантську заяву ifelse.
dwidel

Проблема в Select Case Trueтому, що він виглядає так, ніби він оцінює кожне з Caseтверджень і запускає код для кожного з них, що відповідає дійсності. Але насправді він оцінює їх один за одним і запускає код лише для першого, який є істинним. У Ifцьому відношенні синтаксис значно чіткіший ( If...Else If...Else If...Else).
Райан Лунді

31

Одним з основних застав, який я весь час використовую, є ключове слово With :

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

Мені просто не подобається набирати більше, ніж треба!


Але це також створює деякі приховані помилки, особливо коли у вас є With With
Варун Махаджан,

2
Я навіть не знав, що ти можеш поставити нове в межах існуючого. Це просто неохайно!
Боб Кінг

2Bob: я не є неохайним, я б запропонував .. це просто мовна конструкція, яку слід обережно використовувати. Для встановлення безлічі властивостей у послідовних рядках чудово, але знайти випадкову.
ChrisA

2
Бажаєте, C # це має? Або я спав і це вже в С # приховані функції вже відповідає ...? ;-)
peSHIr

1
@Boo: Ти маєш рацію, але все одно прикро, що ти не можеш додати його до списку спостереження.
Meta-Knight

31

Найкращий і простий аналізатор CSV:

Microsoft.VisualBasic.FileIO.TextFieldParser

Додавши посилання на Microsoft.VisualBasic, це може бути використане будь-якою іншою мовою .Net, наприклад C #


5
+1 Дивно, як люди з C # бігають до FileHelpers, не задумуючись про це. Я впевнений, що FileHelpers відмінний, але це зовнішня залежність.
MarkJ

@MarkJ Я припускаю, що це через незнання
Натан Кооп

Я гуглив чорт, намагаючись знайти цей клас, і ніколи цього не робив, спасибі за те, що його виклали!
pingoo


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 

Крім того, це не те саме, що просто оголосити його як Спільного члена класу; елементи, оголошені таким чином, гарантовано також є безпечними для потоків. У цьому сценарії це не має значення, оскільки вираз ніколи не зміниться, але є й інші, де це може бути.


1
Одним із способів цього є збереження лічильника, який збільшуватиметься кожного разу, коли метод викликається. Якщо змінна позначена "Статична", вона не буде повторно реалізована при кожному виклику методу; вона буде ініціалізована лише під час першого дзвінка, а потім збереже своє значення.
Райан Лунді

З цієї причини учасників статичного класу називають "спільними" у VB.NET
Enrico Campidoglio

Статична - це погана форма у VB.NET навіть більше, ніж у класичному VB. Статистичних змінних слід уникати, коли і де це можливо.
Сем Топор

6
@Boo - це надзвичайно приємно. Яке ваше виправдання? Я думаю, що статичні змінні корисні.
MarkJ

4
Статичний, використаний як у наведених вище прикладах, дозволяє унікальну форму інкапсуляції: змінні рівня класу, які мають область рівня методу. Без цього вам доведеться створити змінну рівня класу, яка була б доступною для будь-якого члена класу, навіть якщо ви використовуєте її лише одним методом.
Райан Лунді

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

1
Я навчився цього важким шляхом, намагаючись знайти голку в мільйон рядків коду. регулярний та цілочисельний поділ. хороша порада!
Джейсон Ірвін

23

Мені дуже подобається "Мій" Іменний простір, який був представлений у Visual Basic 2005. Мій це ярлик для декількох груп інформації та функціональності. Він забезпечує швидкий та інтуїтивний доступ до таких типів інформації:

  • My.Computer : доступ до інформації, пов'язаної з комп'ютером, наприклад файловою системою, мережею, пристроями, системною інформацією тощо. Він забезпечує доступ до ряду дуже важливих ресурсів, включаючи My.Computer.Network, My.Computer.FileSystem і My . Комп'ютер. Принтери.
  • My.Application : доступ до інформації, що стосується конкретного додатка, наприклад, імені, версії, поточного каталогу тощо.
  • My.User : доступ до інформації, що стосується поточного аутентифікованого користувача.
  • My.Resources : Доступ до ресурсів, використовуваних додатком, що перебуває у файлах ресурсів, строго набраним способом.
  • Мої настройки : Доступ до налаштувань конфігурації програми у чітко набраному вигляді.

Це просто чудово, і кожен хлопець vb.net там повинен знати речі в моєму просторі імен, це так корисно.
д-р. зло

Мій. * FTW :).
д-р. зло

3
Це якось корисно, але я ненавиджу занедбане ім’я. Нагадує мені про це secretgeek.net/refactvb.asp
MarkJ

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

здається крутим, але якщо мені це колись знадобиться, я думаю, що я зробив щось не так ;-). Це просто здається проти принципу KISS.
chrissie1

4
Це дійсно, дуже корисно, коли ви хочете переконатися, що кожна раковина отримує подію, навіть якщо один або кілька кидають виняток.
Джонатан Аллен

Ще одне значення (я щойно прочитав його на сайті MSDN) - якщо ваш клас кидає безліч подій, ви можете змусити його використовувати хеш-таблицю / словник як контейнер, а не оголошувати поле для кожної події. msdn.microsoft.com/en-us/library/8627sbea(VS.71).aspx
торіальний

Класно. Я подумав, що це одна з особливостей, які розрізняють C # і VB.NET (як в одній банці, але в іншому немає для цього синтаксису). Приємно хоча б знати, що я помилявся в цьому відношенні.
peSHIr

21

Я щойно знайшов статтю, яка розповідає про "!" Оператор, також відомий як "оператор пошуку словника". Ось уривок зі статті за адресою: http://panopticoncentral.net/articles/902.aspx

Технічна назва для! Оператор - "оператор пошуку словника". Словник - це будь-який тип колекції, який індексується ключем, а не числом, подібно до того, як записи в англійському словнику індексуються словом, яке ви хочете визначити. Найпоширеніший приклад типу словника - System.Collections.Hashtable, який дозволяє додавати (ключ, значення) пар до хештету, а потім отримувати значення за допомогою клавіш. Наприклад, наступний код додає три записи до хештету, і шукає одну з них за допомогою клавіші "Pork".

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

Щоб отримати дійсно технічне значення, x! Y працює, якщо x має властивість за замовчуванням, яка бере параметр String або Object. У цьому випадку x! Y змінюється на x.DefaultProperty ("y"). Цікавою стороною зауваження є те, що в лексичній граматиці мови є спеціальне правило, щоб все це працювало. The! символ також використовується як тип типу в мові, а символи типу з'їдаються перед операторами. Тож без спеціального правила x! Y буде відскановано як "x! Y" замість "x! Y". На щастя, оскільки в мові немає місця, де є два ідентифікатори підряд, ми просто ввели правило, що якщо наступний символ після! це початок ідентифікатора, ми вважаємо! бути оператором, а не типовим персонажем.


11
Це одна з тих особливостей, яку я використовував тоді навмисно забув. Це заощаджує кілька натискань клавіш, але помилки з моїм підсвічуванням коду та читальністю. забувши знову право .... ЗАРАЗ
STW

3
Цікаво, але не дуже корисно. Це такі речі, над якими працює команда VB, замість додавання відсутніх функцій, таких як ключове слово дохідність? : P
Meta-Knight

5
Ця функція перенесена для сумісності з VB3 (AFAIK)
Eduardo Molteni

1
чи мають ті класи, які реалізують індекс, що має ключ, спільний інтерфейс, від якого вони успадковуються? як IKeyed аналогічно цілочисельним індексованим контейнерам реалізувати IENumberable?
Маслоу

2
Ця функція також працює з DataRows (тобто dr! ID), який ДУЖЕ зручний у LINQ для DataSets.
Пол

19

Це вбудований і певна перевага перед C #. Можливість реалізації методу інтерфейсу без використання однойменного імені.

Як от:

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

End Sub

Я впевнений, що ви можете зробити щось подібне в C #. У VB.NET його просто вимушене, а в C # його необов'язкове?
Jesper Blad Jensen

5
Ви також можете зробити підприватну приватну, що є прекрасним способом приховати такі речі, як виклики до загальних застарілих версій інтерфейсів.
Крейг Гідні

3
Це може бути хорошою ідеєю. Класичним прикладом може бути, якщо ви хочете метод Public Close, який також виступає вашою реалізацією Dispose для IDisposable.
MarkJ

1
Це також дуже корисно, якщо вам трапляється реалізувати два інтерфейси, які мають загальну назву методу.
Ерік Ніколсон

Я бачив це і завжди хотів, щоб цього не зробив. Не слід допускати.
FastAl

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
Боже мій ... це чудова особливість, хоча я не думаю, що знав би, що це робив, якби прочитав це в чужому коді. Якщо вам доведеться коментувати це лише для того, щоб знати, що він робить, ви, можливо, також зробили змінну скидання для передачі замість цього.
mattmc3

7
Це насправді побічний ефект від використання дужок - Парентез створює тимчасове значення того, що знаходиться всередині, навіть якщо лише один предмет. Цей ефект Вбивство мене в vb6 - Sub дзвінки не брали паронів, але мені, що прийшов від C, інстинктивно поставив паролі. 6.0 підірвався за декількома параметрами, але для одного параметра sub, він із задоволенням передав тимчасове значення і відмовився вшановувати мій 'byref'. Траплялося приблизно кожні 3 роки, приблизно про час, який знадобився мені, щоб забути останній випадок.
FastAl

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

Ого, це супер круто! Я бачив це під час використання веб-служб тощо, але я не знав, що ви можете зробити це будь-яким звичайним методом.
RichC

2
Напевно, дуже зручний інструмент, коли ви стикаєтесь з методом, який бере занадто багато аргументів. Я намагаюся назвати кожен параметр і поставити ім'я: = значення у свій власний рядок. Це набагато більш інтуїтивно зрозуміло та зрозуміло для методів, які приймають> 5 (моє правило).
STW

Особливо корисно для автоматизації Office, де вам доведеться впоратися з методами з десятками необов’язкових аргументів.
MarkJ

1
Що також цікаво, це те, що ви можете змішати два: почніть з вказівки необхідних параметрів для того, щоб перейти до названих параметрів для необов'язкових аргументів!
RBarryYoung

15

Оператор Use є новим, ніж VB 8, C # мав його з самого початку. Він закликає розпоряджатися автоматично для вас.

Напр

Using lockThis as New MyLocker(objToLock)

End Using

23
Варто зауважити (тільки тому, що я забув принаймні двічі), що ви можете мати один оператор Використання оператора, який обгортає кілька одноразових об'єктів. Синтаксис: "Використання objA як нового об'єкта, objB як новий об'єкт ...." Це набагато чистіше, ніж введення декількох операторів Використання.
STW

Безумовно, один із моїх улюблених також.
Сем Топор

14

Псевдоніми імпорту також значною мірою невідомі:

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form

1
Я думаю, що ми мали таку саму ідею.
chrissie1

3
@Boo - ось простий приклад, коли псевдоніми імпорту не є злими. stackoverflow.com/questions/92869/…
torial

Гаразд - є очевидний шлях для зловживань, але незалежно від рейтингу @ torial це чудова особливість. Щоразу, коли я включаю System.Text.RegularExpressions, я ризикую зіткнутись з іменем із класом "Group", оскільки це загальне ім'я класу. Псевдонім дозволяє уникнути необхідності повністю кваліфікувати неоднозначні класи, що є величезною економією часу та фактично підвищує читабельність при правильному використанні. Ця функція чудова, але ваш конкретний приклад начебто запрошує насмішок - вибачте, сказати.
mattmc3

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


Чому б вам хотілося це робити? Я не можу уявити випадок використання, коли вам потрібно знати кількість підписників на подію в VB.
Конрад Рудольф

За певних обставин, C # викидає виняток, якщо ви піднімаєте подію і немає обробників. VB.Net не буде. Звідси необхідність перевірки.
Джоель Куехорн

2
Я використовував це для події бізнес-об'єкта, яка піднімала абонентам повідомлення про помилки перевірки. Я хотів перевірити, чи подія обробляється так, щоб я знав, що отримуються помилки перевірки. Інакше у мене бізнес-об’єкт кинув виняток.
Technobabble

2
Ще одне зручне використання цього приватного члена - отримання списку викликів події. Я використовував його в декількох випадках, щоб асинхронізувати подію для всіх абонентів (не дозволяє слухачеві А змінити подію до того, як слухач B отримає її; також не дозволяє слухачеві А затримати доставку до слухача B). Я багато використовував це в спеціальних сценаріях синхронізації даних, а також в API.
STW

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

Я думаю, що цей приклад буде кращим, якби ви не використовували "If" в якості прикладу ключового слова.
Шон Гоф

4
timer.Start і timer.Поверніть весну на думку, як приклади
успішного

5
+1, щоб вказати на неї застереження. Існує кілька базових класів, для яких потрібно правильно вирішити, наприклад, [Асамблея]
STW

5
[Enum] - ще один хороший приклад випадку, коли вам потрібні дужки, щоб використовувати клас замість ключового слова.
Райан Лунді

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>Звичайно, вам не потрібно використовувати тег; ви можете використовувати будь-який тег, який вам подобається.)


3
<q>буде хорошим тегом, подібним до використання в Perl / Ruby. У всякому разі, це досить приємна ідіома. ПОДІБНО ДО!
Конрад Рудольф

Яка геніальна ідея. Дякую
Джеремі

12

DateTime можна ініціалізувати, обклавши дату номером #

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

Ви також можете використовувати висновок типу разом із цим синтаксисом

Dim independanceDay = #7/4/1776#

Це набагато приємніше, ніж використовувати конструктор

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

6
Ні, якщо у вас є опція Strict On
danlash

12

Ви можете мати 2 рядки коду лише в одному рядку. звідси:

Dim x As New Something : x.CallAMethod

whoa ... Я думав, що це можливо тільки з / класом та спадкуванням
Jason

Не забувайтеCall (New Something).CallAMethod()
Джонатан Аллен

Це власник від MS-Basic в Apple] [! У моєму магазині мене б так само висміяли за використання Gotos: - /
FastAl

Більшу частину часу цього слід уникати, але там, де я люблю це використовувати, це є випадки, коли рядки справді короткі, наприклад, справа 4: x = 22
dwidel

11

Необов’язкові параметри

Додаткові можливості набагато простіше, ніж створення нових перевантажень, таких як:

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

1
Я не знав, що C # збирається їх отримати. Вони приємні, але ви повинні бути обережними, щоб використовувати їх лише там, де ви впевнені, що код не споживається C #, оскільки він не підтримує їх. FxCop / Аналіз коду підкаже замість цього перевантажити метод.
STW

... Я просто знайшов велике використання для необов'язкових параметрів, але все ще не вдавав їх у виробничий код. Я написав короткий пост про це на своєму сайті: yoooder.com/wordpress/?p=62
STW

2
Ах, я так зневажаю це ... Але корисно для автоматизації Office
dance2die

9

Справа з заголовком у VB.Net може бути досягнута старим VB6 fxn:

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

1
його також у класі textinfo. не впевнений, який простір імен є. Мабуть system.text
Шон

Вам краще бути .net мовою нейтральною і використовувати клас Globalization TextInfo для перетворення ToTitleCase. Якщо код коли-небудь потребує перетворення на C #, у вас буде багато маленьких натовпів, для яких потрібен Microsoft.VisualBasic
Jeremy

9

Властивості з параметрами

Я займався деяким програмуванням на C # і виявив функцію, якої не було у VB.Net, але тут не згадували.

Приклад того, як це зробити (як і обмеження c #), можна побачити на: Використання типових властивостей get set у C # ... з параметрами

Я вийняв код з цієї відповіді:

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

Це цікаво, але я не зовсім впевнений, де це було б корисно. myObj.Something ("abc") більше схожий на те, що ви отримуєте доступ до функції, ніж до властивості. Не впевнений, що це купує у вас.
mattmc3

Я ненавиджу неоднозначність. Що це повинно бути. Метод або властивість. Деякі інструменти рефакторингу пропонують створити і те, і інше в певних ситуаціях, схоже, вони навіть не знають ...
brumScouse
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.