VB.NET'in Gizli Özellikleri?


121

C # 'ın Gizli Özelliklerine göz atmayı epeyce öğrendim ve VB.NET için benzer bir şey bulamadığımda şaşırdım.

Öyleyse gizli veya daha az bilinen özelliklerinden bazıları nelerdir?

Yanıtlar:


128

Exception WhenFıkra büyük ölçüde bilinmemektedir.

Bunu düşün:

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
belirli bir SQLException yakalamak istiyorsanız kullanışlıdır, -2 diyelim ki doğru hatırlıyorsam ağ zaman aşımıdır: ex.code = -2
Pondidum

Vaov! Bunu sadece okudum ve geçen hafta yazdığım bir dene / yakala bloğunu basitleştirmek için hemen kullanmaya başladım. Ben asla yeni olmadım.
John M Gant

1
+1 Ve işte burada NET CLR ekip blogu istisna filtrelerinin neden yararlı olduğunu açıklıyor bloglar.msdn.com/clrteam/archive/2009/02/05/…
MarkJ

5
Bu sadece gizli değil, aynı zamanda C # 'ta da mevcut değil.
Cheeso

82

Özel Enums

VB'nin gerçek gizli özelliklerinden biri , genişletilmiş işlevselliğe sahip completionlistkendine benzer Enumtürler oluşturmak için kullanılabilen XML dokümantasyon etiketidir . Yine de bu özellik C # ile çalışmaz.

Yakın tarihli bir kodumdan bir örnek:

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

Şimdi, olarak bildirilen bir değişkene bir değer atarken Rule, IDE, .NET Core'dan olası değerlerin bir IntelliSense listesini sunar RuleTemplates.

/DÜZENLE:

Bu, IDE'ye dayanan bir özellik olduğu için, onu kullandığınızda nasıl göründüğünü göstermek zor, ancak sadece bir ekran görüntüsü kullanacağım:

Tamamlama listesi iş başında http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

Aslında, IntelliSense, bir Enum.


İlginç - tükettiğinizde bunun nasıl göründüğüne dair bir örnek gösterebilir misiniz?
Brian MacKay

Görünüşe göre birisi doğrudan Kural yapıcısını çağırarak kendi kuralını oluşturabilir mi? Eğer öyleyse ve bunu durdurmak istiyorsanız, kurucuyu kütüphanenizde "Arkadaş" olarak ilan edebilir misiniz?
Joel Coehoorn

Joel, örnek kodumda bunu kasıtlı olarak yasaklamadım. Bunun yerine, kullanıcıya bazı ortak kurallar sunuyorum ve kendi özel kurallarının oluşturulmasına izin veriyorum. Yapıcıyı işaretleyerek friendveya enum: Ruleyerine aynı sınıfı kullanarak bunu elbette önleyebilirsiniz RuleTemplate.
Konrad Rudolph

Gizli yararlı özellik kullanımlarının olduğu bir yer var mı? Bu yüz yüze inanılmaz görünüyor, ancak henüz onu nerede kullanacağımdan ya da bazı durumlarda bir jenerik numaralandırmalarla sınırlı olma becerisine sahip olmayan birincil bir yakınmayı çözüp çözemeyeceğinden emin değilim.
Maslow

@Maslow: Burada bir nitelik yok. Bu bir xml yorumudur.
Joel Coehoorn

49

Beğen karşılaştırma işlecini fark ettiniz mi?

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

MSDN'den daha fazlası

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
bir dakika ne? Bu benim için yeni! Hmm, bu, VB.NET string manipülasyonu alternatifinden çok daha iyi bir helluva: D
STW

.. !! Birkaç vb.net projesinde çalışmama rağmen bunu bilmiyordum! İlginç özellik ...
Meta-Knight

woooooooooooooooooooooooow! Teşekkürler! bu harika! ELinq, DLinq'de de çalışıyor mu? XLinq ne olacak?
Shimmy Weitzhandler

@dotjoe Hmm? Bu küreler hakkında "tembel" hiçbir şey yok.
Josh Lee

Bu nasıl işliyor, kaputun altında neler oluyor? Reg ex libraries ile eşanlamlı mı?
brumScouse

48

typedefs

VB ilkel bir tür bilir typedefile Importtakma adı:

Imports S = System.String

Dim x As S = "Hello"

Bu, genel türlerle birlikte kullanıldığında daha kullanışlıdır:

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

2
lütfen bir örnek gösterin, İçe Aktarma kelimesi IDE'mde tanınmıyor.
Shimmy Weitzhandler

5
Importsolmalı. ;-) Her nasılsa, bu hata neredeyse bir yıl boyunca fark edilmedi (ve 28 olumlu oy aldı).
Konrad Rudolph

Bir jenerik için varsayılanlarla nasıl yeni bir "tür" yapabileceğimi hep merak etmişimdir! Güzel!
eidylon

3
İthalat, İthalat, İthalat, her neyse! Sheesh, onlara oy vermeden önce bu yazıları okuduğumuzu düşünüyorsun !
MarkJ

Xunit'i görsel stüdyo testlerinde kullanmak için harika yaniImports Assert = xUnit.Assert
wheelibin

45

Ah! ve XML Değişmezlerini unutmayın .

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

Ben de öyle söyleyecektim. Aslında, XML hazır değerlerini, amaçlanmadığı bir amaç için kullandım. Javascript ... swortham.blogspot.com/2009/03/vb-2008.html
Steve Wortham

9
Diğer şeylerin yanı sıra, çirkin dize kaçışının üstesinden gelmek için XML Değişmezlerini kullanabilirsiniz, örneğin, kendileri çift tırnak içeren dizeler kullandığınızda. Sadece bir XML DizgeselSabit içinde dize koymak ve bunun gibi Değerini, çağrı: <string>This string contains "quotes" and it's OK.</string>.Value . (Ben her alan tırnak içinde oldu CSV dosyalarını ayrıştırma testler yazarken özellikle kullanışlı O olur bulunamadı değil de elle tüm bu tırnak kaçmayı olmuştur eğlenceli benim test hatları.)
Ryan Lundy

2
@Kyralessa: +1, harika yorum. Aslında, çok satırlı dizeleri belirtmenin harika bir yoludur (SQL ifadelerini kucaklar, vb.)
Heinzi

Satır içi XML, şimdiye kadar tasarlanmış en kötü VB.NET özelliklerinden biridir. Kanıtlanmamış gerçek.
Grant Thomas

39

Nesne başlatma da burada!

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

1
Kıvırcık tellerle gittiklerine inanamıyorum. Zaten bir With deyimimiz var .. bu sözdizimini yeniden kullanabilirlerdi.
Sam Axe

2
Biliyorum, sadece size yolda hiç polis olmadığını göstermek için yapıldı ... lol JK
Shimmy Weitzhandler

4
Bu, derleyici yazarlarının tümü özünde C / C ++ programcıları olduğunda ne olur. C sözdizimini diğer dillere kaydırmaya devam ediyorlar çünkü daha iyi bir şey düşünemiyorlar.
RBarryYoung

38

DirectCast

DirectCastbir harikadır. Yüzeyde, CTypebir nesneyi bir türden diğerine dönüştürmesi açısından operatöre benzer şekilde çalışır . Ancak, çok daha katı bir kurallar dizisi ile çalışır. CTypegerçek davranışı bu nedenle genellikle opaktır ve hangi tür dönüşümün yürütüldüğü hiç belli değildir.

DirectCast yalnızca iki farklı işlemi destekler:

  • Bir değer türünün kutudan çıkarılması ve
  • sınıf hiyerarşisinde upcasting.

Diğer türler çalışmayacaktır (örneğin, bir'den a'ya kutucuğu Integerkaldırmaya çalışmak Double) ve bir derleme zamanı / çalışma zamanı hatasıyla sonuçlanacaktır (duruma ve statik tip kontrolüyle neyin tespit edilebileceğine bağlı olarak). Bu yüzden kullanıyorumDirectCast , amacımı en iyi şekilde yakaladığından, mümkün olduğunda : duruma bağlı olarak, bilinen türden bir değeri kutudan çıkarmak veya bir yukarı yayın gerçekleştirmek istiyorum. Hikayenin sonu.

CTypeÖte yandan kullanmak , kod okuyucuyu programcının gerçekte ne amaçladığını merak etmesine neden olur çünkü kullanıcı tanımlı kodu çağırmak da dahil olmak üzere her türlü farklı işleme çözüm getirir.

Bu neden gizli bir özellik? VB ekibi, kodu daha tekdüze hale getirmek için (aslında daha hızlı olmasına rağmen!) Kullanımını engelleyen bir kılavuz 1 yayınladı DirectCast. Bunun tersine çevrilmesi gereken kötü bir kılavuz olduğunu savunuyorum: Mümkün olduğunda DirectCast, daha genel CTypeoperatörü tercih edin. Kodu çok daha net hale getirir. CTypeÖte yandan, yalnızca bu gerçekten amaçlanmışsa, yani bir daraltma CTypeoperatörü (cf. operatör aşırı yükleme ) çağrılması gerektiğinde çağrılmalıdır.


1) Kılavuza bir bağlantı kuramıyorum ama Paul Vick'in konuyla ilgili görüşünü buldum (VB ekibinin baş geliştiricisi):

Gerçek dünyada, farkı neredeyse hiç fark etmeyeceksiniz, bu yüzden CType, CInt, vb. Gibi daha esnek dönüştürme operatörleriyle de gidebilirsiniz.


(DÜZENLE Zack: Buradan daha fazla bilgi edinin: VB.NET'te nasıl yayın yapmalıyım? )


Aslında TryCast () 'ı biraz daha çok seviyorum. Bir istisna atmaz, sadece oyuncu kadrosu başarısız olursa Nothing döndür. Yayının sık sık başarısız olmasını bekliyorsanız, TypeOf x Is T ... DirectCast'den (x, T) daha hızlıdır ve DirectCast başarısız olursa istisnayı yakalamaktan kesinlikle daha hızlıdır.
Bob King

6
DirectCast () ve TryCast (), bir çift olarak doğru şekilde kullanıldığında paha biçilmezdir. DirectCast (), atılan nesnenin her zaman hedef türü olması bekleniyorsa kullanılmalıdır (eğer değilse, bir hata alırsınız, bu beklenmedik bir durum olduğu için iyi bir şeydir). TryCast (), dönüştürülen nesne hedef tipte veya birkaç hedef tipinde olabiliyorsa kullanılmalıdır. Birini veya diğerini özel olarak kullanmak, fazladan ek yüke yol açar (eğer x tipi y ise, o zaman directcast (x, y) verimsizdir) veya geçerli hatalardan kaçınmaya (nesnenin her zaman hedef türü olması gereken durumlarda TryCast () kullanarak )
STW

Yoooder:% 100 doğru. O TryCastzamanlar bahsetmediğim için utanç verici, çünkü ağırlıklı olarak yaygın kullanımla seçmem gereken bir kemiğim vardı CType.
Konrad Rudolph

@Maslow: Elbette öyle değil, Enums değer türleri olduğundan ve TryCastbelgelere göre yalnızca başvuru türlerinde çalışır.
Konrad Rudolph

+1: Heh. Kabul etmeliyim, sadece bunu okudum ve "Oh evet, DirectCast, bunu nasıl unuttum?" Diye düşündüm. Ve sonra onu bir sonraki kod satırımda kullandım (CType'ı gerçekten sevmediğim için).
RBarryYoung

37

If koşullu ve birleştirme operatörü

Onu nasıl gizli olarak adlandıracağınızı bilmiyorum, ama Iif ([ifade], [doğruysa değer], [yanlışsa değer]) As Nesne işlevi sayılabilir.

Kullanımdan kaldırıldığı kadar gizli değil ! VB 9 If, çok daha iyi olan ve tam olarak C # 'ın koşullu ve birleştirme operatörü gibi çalışan (ne istediğinize bağlı olarak) operatöre sahiptir:

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

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

Başka bir örnek göstermek için düzenlendi:

Bu birlikte çalışacak If(), ancak bir istisnaya neden olacakIIf()

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

Güzel, bunu bilmiyordum! Dün IIF'yi kullandım, bu yüzden bu kod bloğunu tekrar ziyaret edeceğim.
Sean Gough

4
VS 2005'e bunu söyle. Hepimiz en yeni ve en iyiyle çalışamayız.
Sam Erwin

3
@Slough, saçmalık. Bu yöntem% 100 tür güvenlidir ve (ikinci ve üçüncü) bağımsız değişkeniyle aynı türde bir nesne döndürür. Ek olarak, bağımsız değişkenler arasında genişleyen bir dönüşüm olmalıdır, aksi takdirde türler eşleşmediğinden bir derleme hatası olacaktır.
Konrad Rudolph

1
Evet, tür güvenli olmayan
IIf'si

2
@ Br.Bill Aslında, C ve Perl'in operatörüne tamamen eşdeğerdir:? , sadece basitleştirilmiş bir sürüm değildir.
Konrad Rudolph

32

Bu güzel bir tanesidir. VB.Net içindeki Select Case deyimi çok güçlüdür.

Elbette standart var

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

Ama dahası var ...

Aralıklar yapabilirsiniz:

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

Ve daha fazlası ...

(İyi bir fikir olmasa da) birden çok değişken üzerinde mantıksal kontroller yapabilirsiniz:

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
Aslında bir çifti gözden kaçırdınız: a) birden fazla değişkeni test etmek için "Case A, B, ..." formunu kullanmak ve hatta c) ":" öğesini in- yürütme ifadesini koşul cümlesi ile hizalayın (çoğu kişi bundan hoşlanmasa da).
RBarryYoung

6
Lütfen Select Case True kullanmayın. Sadece bir If ifadesi kullanın.
Ryan Lundy

4
Select Case True okumayı dev bir ifelse ifadesinden çok daha kolay buluyorum.
dwidel

İle sorun Select Case Truetam o görünüyor bu değerlendirir sanki her bir Casebeyan ve doğrudur her biri için kod çalışır. Ama aslında onları tek tek değerlendiriyor ve yalnızca doğru olan ilk kod için çalıştırıyor . IfBu bağlamda sözdizimi çok daha nettir ( If...Else If...Else If...Else).
Ryan Lundy

31

Her zaman kullandığım önemli bir zaman kazandıran, With anahtar kelimesidir:

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

Yazmayı mecbur olduğumdan daha fazla sevmiyorum!


Ama aynı zamanda size With içinde birlikte var, özellikle bazı gizli hataları oluşturmak
Varun Mahajan

2
Mevcut bir Birlikte yeni bir With koyabileceğinizi bile bilmiyordum. Bu çok saçma!
Bob King

2Bob: özensiz değil, önerebilirim .. sadece dikkatle kullanılacak bir dil yapısı. Ardışık satırlarda birçok özelliği ayarlamak harika, ancak karmaşık bir kod parçasında rastgele bir.
ChrisA

2
Keşke C # buna sahip mi? Yoksa uyumuş muydum ve C # gizli özelliklerde zaten cevaplar var mı ...? ;-)
peSHIr

1
@Boo: Haklısın ama onu İzleme listesine ekleyememek yine de can sıkıcı bir durum.
Meta-Knight

31

En iyi ve kolay CSV ayrıştırıcısı:

Microsoft.VisualBasic.FileIO.TextFieldParser

Microsoft.VisualBasic'e bir referans ekleyerek, bu başka herhangi bir .Net dilinde kullanılabilir, örneğin C #


5
+1 C # milletinin bunu hiç düşünmeden FileHelpers'a koşması tuhaf. Eminim FileHelpers mükemmeldir, ancak bu harici bir bağımlılıktır.
MarkJ

@MarkJ Cehalet yüzünden olduğunu düşünüyorum
Nathan Koop

Google'da bu sınıfı bulmaya çalışmaktan cehennemde bulundum ve asla yapmadım, sardığın için teşekkürler!
pingoo


25

Yöntemlerde statik üyeler.

Örneğin:

Function CleanString(byval input As String) As String
    Static pattern As New RegEx("...")

    return pattern.Replace(input, "")
End Function

Yukarıdaki işlevde, kalıp düzenli ifadesi, işlevin kaç kez çağrıldığına bakılmaksızın yalnızca bir kez oluşturulacaktır.

Başka bir kullanım, etrafta "rastgele" bir örnek tutmaktır:

Function GetNextRandom() As Integer
    Static r As New Random(getSeed())

    Return r.Next()
End Function 

Ayrıca bu, onu sınıfın bir Paylaşılan üyesi olarak bildirmekle aynı şey değildir; bu şekilde bildirilen öğelerin de iş parçacığı açısından güvenli olduğu garanti edilir. İfade asla değişmeyeceği için bu senaryoda önemli değil, ancak olabileceği yerde başkaları da var.


1
Bunun bir kullanımı, yöntem her çağrıldığında artacak bir sayaç tutmaktır. Değişken Statik olarak işaretlenmişse, her yöntem çağrısında yeniden başlatılmaz; yalnızca ilk çağrıda başlatılacak ve daha sonra değerini koruyacaktır.
Ryan Lundy

Bu yüzden statik sınıf üyeleri adında VB.NET içinde "ortak" olan nedenidir
Enrico Campidoglio

Statik, VB.NET'te klasik VB'de olduğundan daha kötü bir formdur. Statik değişkenlerden mümkün olduğunca ve her yerde kaçınılmalıdır.
Sam Axe

6
@Boo - bu oldukça kapsamlı. Gerekçen nedir? Statik değişkenlerin yararlı olduğunu düşünüyorum.
MarkJ

4
Yukarıdaki örneklerde olduğu gibi kullanılan statik, benzersiz bir kapsülleme biçimine izin verir: yöntem düzeyinde kapsama sahip sınıf düzeyinde değişkenler. Bu olmadan, yalnızca bir yöntemde kullanıyor olsanız bile, herhangi bir sınıf üyesinin erişebileceği bir sınıf düzeyinde değişken oluşturmanız gerekir.
Ryan Lundy

25

Fi'de bu operatörler arasında farklılıklar vardır:

/olan Double
\bir Integerkalan göz ardı

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
Bunu bir milyon satır kodda bir iğne bulmaya çalışırken zor yoldan öğrendim. normal ve tamsayı bölme. iyi bahşiş!
Jason Irwin

23

Visual Basic 2005'te tanıtılan "My" Ad Alanını gerçekten çok seviyorum . My , çeşitli bilgi ve işlevsellik gruplarına bir kısayol. Aşağıdaki bilgi türlerine hızlı ve sezgisel erişim sağlar:

  • Benim bilgisayarım : Dosya sistemi, ağ, cihazlar, sistem bilgileri vb. Gibi bilgisayarla ilgili bilgilere erişim sağlar My.Computer.Network, My.Computer.FileSystem ve My.Computer.Network gibi çok önemli bir dizi kaynağa erişim sağlar. .Computer.Printers.
  • My.Application : Ad, sürüm, geçerli dizin vb. Gibi belirli bir uygulama ile ilgili bilgilere erişim.
  • My.User : Geçerli kimliği doğrulanmış kullanıcıyla ilgili bilgilere erişim.
  • My.Resources : Kaynak dosyalarında bulunan uygulama tarafından kullanılan kaynaklara kesin olarak yazılmış bir şekilde erişim.
  • My.Settings : Uygulamanın yapılandırma ayarlarına güçlü bir şekilde yazılmış bir şekilde erişin.

Bu harika ve dışarıdaki her vb.net çalışanı My namespace'deki şeyleri bilmeli, çok kullanışlı.
dr. evil

Benim. * FTW :).
dr. kötü

3
Biraz işe yarıyor ama basitleştirilmiş isimden nefret ediyorum. Bana bu secretgeek.net/refactvb.asp'yi
MarkJ

23

Özel Etkinlikler

Nadiren yararlı olsa da, olay işleme büyük ölçüde özelleştirilebilir:

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

Bu daha sonra aşağıdaki şekilde test edilebilir:

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

havalı görünüyor, ancak buna ihtiyacım olursa yanlış bir şey yapacağımı düşünüyorum ;-). KISS ilkesine aykırı görünüyor.
chrissie1

4
Bir veya daha fazla kişi bir istisna atsa bile her lavabonun olayı aldığından emin olmak istediğinizde gerçekten çok yararlıdır.
Jonathan Allen

Başka bir değer de (onu MSDN sitesinde okudum), sınıfınız çok sayıda olay atarsa, her olay için bir alan bildirmek yerine, onu bir karma tablo / sözlüğü kapsayıcı olarak kullanmaya zorlayabilirsiniz. msdn.microsoft.com/en-us/library/8627sbea(VS.71).aspx
torial

Güzel. Bunu, C # ve VB.NET'i ayıran özelliklerden biri olarak düşündüm (birinde olduğu gibi, ancak diğerinin bunun için sözdizimi yok). En azından bu konuda yanıldığımı bilmek güzel.
peSHIr

21

Az önce "!" Hakkında bir makale buldum. operatör, "sözlük arama operatörü" olarak da bilinir. İşte makaleden bir alıntı: http://panopticoncentral.net/articles/902.aspx

! Öğesinin teknik adı! operatörü "sözlük arama operatörü" dür. Sözlük, tıpkı bir İngilizce sözlükteki girişlerin tanımını istediğiniz kelimeye göre indekslenmesi gibi, bir sayı yerine bir anahtar tarafından indekslenen herhangi bir koleksiyon türüdür. Sözlük türünün en yaygın örneği, hashtable'a (anahtar, değer) çiftleri eklemenizi ve ardından anahtarları kullanarak değerleri almanızı sağlayan System.Collections.Hashtable'dır. Örneğin, aşağıdaki kod bir hashtable'a üç girdi ekler ve bunlardan birini "Domuz Eti" anahtarını kullanarak arar.

Dim Table As Hashtable = New Hashtable
Table("Orange") = "A fruit"
Table("Broccoli") = "A vegetable"
Table("Pork") = "A meat" 
Console.WriteLine(Table("Pork"))

! işleci, dizeleri kullanarak değerlerini indeksleyen herhangi bir sözlük türünden değerleri aramak için kullanılabilir. ! 'Den sonraki tanımlayıcı! arama işleminde anahtar olarak kullanılır. Yani yukarıdaki kod bunun yerine yazılabilirdi:

Dim Table As Hashtable = New Hashtable
Table!Orange = "A fruit"
Table!Broccoli = "A vegetable"
Table!Pork = "A meat"
Console.WriteLine(Table!Pork)

İkinci örnek, birincisine tamamen eşdeğer, ancak en azından gözlerime çok daha hoş görünüyor. Bulduğum birçok yer var! özellikle dizgeye göre indekslenmiş tonlarca koleksiyonun olduğu XML ve web söz konusu olduğunda kullanılabilir. Talihsiz bir sınırlama, aşağıdaki şeyin! yine de geçerli bir tanımlayıcı olması gerekir, bu nedenle anahtar olarak kullanmak istediğiniz dizede geçersiz bir tanımlayıcı karakter varsa,! Şebeke. (Örneğin, "Tablo! AB $ CD = 5" diyemezsiniz çünkü $ tanımlayıcılarda geçerli değildir.) VB6'da ve öncesinde, geçersiz tanımlayıcılardan kaçmak için parantez kullanabilirsiniz (ör. "Tablo! [AB $ CD] "), ancak anahtar kelimelerden kaçmak için köşeli parantez kullanmaya başladığımızda, bunu yapma yeteneğimizi kaybettik. Çoğu durumda,

Gerçekten teknik olmak için, x! Y, x'in parametre olarak bir Dize veya Nesne alan bir varsayılan özelliği varsa çalışır. Bu durumda, x! Y, x.DefaultProperty ("y") olarak değiştirilir. İlginç bir yan not, tüm bunların çalışmasını sağlamak için dilin sözcük gramerinde özel bir kural olmasıdır. ! karakteri aynı zamanda dilde bir yazım karakteri olarak da kullanılır ve yazım karakterleri operatörlerden önce yenir. Dolayısıyla, özel bir kural olmaksızın, x! Y, "x! Y" yerine "x! Y" olarak taranır. Neyse ki, dilde arka arkaya iki tanımlayıcının geçerli olduğu bir yer olmadığından, sadece! bir tanımlayıcının başlangıcıdır, biz! bir operatör olmak ve bir yazı karakteri değil.


11
Bu, kullandığım ve kasıtlı olarak unuttuğum özelliklerden biri. Birkaç tuş vuruşunu kaydeder, ancak kod vurgulama ve okunabilirliğimi karıştırır. yine doğru unutmak .... ŞİMDİ
STW

3
İlginç, ama gerçekten kullanışlı değil. Bu, VB ekibinin verim anahtar kelimesi gibi eksik özellikleri eklemek yerine üzerinde çalıştığı türden şeyler mi? : P
Meta-Knight

5
Bu özellik, VB3'ten (AFAIK) geriye dönük uyumluluk için taşındı
Eduardo Molteni

1
Anahtarlı bir dizini uygulayan sınıfların miras aldıkları ortak bir arabirimi var mı? tıpkı tamsayı dizine alınmış kapların IENumberable uygulamasını uyguladığı gibi?
Maslow

2
Bu özellik aynı zamanda LINQ to DataSets'te ÇOK kullanışlı olan DataRows (yani dr! ID) ile de çalışır.
Paul

19

Bu yerleşiktir ve C # 'a göre kesin bir avantajdır. Aynı adı kullanmak zorunda kalmadan bir arayüz Yöntemi uygulama yeteneği.

Gibi:

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

End Sub

C # dilinde böyle bir şey yapabileceğinizden çok eminim. VB.NET'te sadece zorunlu ve C #'da isteğe bağlı mı?
Jesper Blad Jensen

5
Ayrıca, arabirimlerin genel olmayan kullanımdan kaldırılmış sürümlerine yapılan çağrılar gibi şeyleri gizlemenin harika bir yolu olan alt bölümü özel yapabilirsiniz.
Craig Gidney

3
İyi bir fikir olabilir. Klasik örnek, IDisposable için Dispose uygulamanız olarak da görev yapan bir Public Close yöntemi istiyorsanız olacaktır.
MarkJ

1
Bir yöntem adını paylaşan iki arayüz uygularsanız, bu da oldukça kullanışlıdır.
Eric Nicholson

Bunu gördüm ve hep keşke görmeseydim. İzin verilmemeli.
FastAl

17

ByVal'ı Zorlama

VB'de, bağımsız değişkenlerinizi fazladan bir parantez kümesine sararsanız, yöntemin ByRef bildirimini geçersiz kılabilir ve bir ByVal'a dönüştürebilirsiniz. Örneğin, aşağıdaki kod 4,5,6 yerine 4, 5, 5 üretir

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

Prosedür Çağrısı Tarafından Değiştirilmeyen Bağımsız Değişken - Temel Değişken'e Bakın


6
Aman tanrım ... bu olağanüstü bir özellik, ancak başka birinin koduyla okursam ne yaptığını bileceğimi sanmıyorum. Sadece ne yaptığını bilmek için yorum yapmak zorunda kalırsanız, atıp bırak değişkeninin yerine geçmesini sağlamış olabilirsiniz.
mattmc3

7
Bu aslında parantez kullanımının bir yan etkisidir - Parantez, tek bir öğe bile olsa, içindekinin geçici bir değerini oluşturur. Bu etki, vb6'da BENİ ÖLDÜRDÜ - Alt çağrılar parens almadı, ancak C'den geldiğimde parensleri içgüdüsel olarak içeri soktum. 6.0 birden fazla parametreyi patlattı, ancak bir parametre subs için, mutlu bir şekilde geçici bir değer geçti ve benim 'byref'. Yaklaşık 3 yılda bir, son olayı unutmam için geçen sürede oldu.
FastAl

16

Parametreleri ada göre geçirmek ve böylece onları yeniden sıralamak

Sub MyFunc(Optional msg as String= "", Optional displayOrder As integer = 0)

    'Do stuff

End function

Kullanımı:

Module Module1

    Sub Main()

        MyFunc() 'No params specified

    End Sub

End Module

Ayrıca herhangi bir sırada ": =" parametre belirtimi kullanılarak çağrılabilir:

MyFunc(displayOrder:=10, msg:="mystring")

Vay canına, bu çok havalı! Bunu Web Hizmetlerini vb. Kullanırken gördüm, ancak bunu herhangi bir normal yöntemle yapabileceğinizi bilmiyordum.
RichC

2
Çok fazla argüman alan bir yöntemle karşılaştığınızda kesinlikle çok kullanışlı bir araçtır. Her bir parametreyi adlandırmaya ve name: = değerini kendi satırına koymaya çalışıyorum. > 5 (benim temel kuralım) parametre alan yöntemler için çok daha sezgisel ve temiz.
STW

Düzinelerce isteğe bağlı bağımsız değişkenle yöntemlerle başa çıkmanız gereken Office otomasyonu için özellikle kullanışlıdır.
MarkJ

1
Ayrıca harika olan , ikisini karıştırabilmenizdir : sırayla gerekli parametreleri belirleyerek başlayın, ardından isteğe bağlı argümanlar için adlandırılmış parametrelere geçin!
RBarryYoung

15

Using deyimi VB 8 itibariyle yenidir, C # en başından beri kullanmıştır. Sizin için otomatik olarak imha etme çağrısı yapar.

Örneğin

Using lockThis as New MyLocker(objToLock)

End Using

23
Kayda değer (sadece en az iki kez unuttuğum için) bir tane kullanabileceğinizi belirtmek gerekir. Sözdizimi "objA'yı yeni nesne olarak, objB'yi yeni nesne olarak kullanmak ...." şeklindedir. Birden çok Using deyimini iç içe yerleştirmekten çok daha temizdir.
STW

Kesinlikle benim favorilerimden biri.
Sam Axe

14

İçe aktarma takma adları da büyük ölçüde bilinmemektedir:

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form

1
Sanırım aynı fikirdeydik.
chrissie1

3
@Boo - işte içe aktarma takma adlarının kötü olmadığı basit bir örnek. stackoverflow.com/questions/92869/…
torial

Tamam - kötüye kullanım için bariz bir yol var, ancak @ torial'in rantı ne olursa olsun bu harika bir özellik. System.Text.RegularExpressions'ı her eklediğimde, bu ortak bir sınıf adı olduğu için "Group" sınıfıyla ad çarpışmaları yaşama riskini alırım. Diğer ad, muazzam bir zaman tasarrufu sağlayan ve düzgün kullanıldığında okunabilirliği gerçekten artıran belirsiz sınıfları tam olarak nitelendirmek zorunda kalmanızı önler . Bu özellik harika, ancak sizin özel örneğiniz biraz alay konusu oluyor - üzgünüm.
mattmc3

14

Aşağıdaki olay bildirimini düşünün

Public Event SomethingHappened As EventHandler

C # 'da, aşağıdaki sözdizimini kullanarak etkinlik abonelerini kontrol edebilirsiniz:

if(SomethingHappened != null)
{
  ...
}

Ancak, VB.NET derleyicisi bunu desteklemez. Aslında, IntelliSense'te görünmeyen gizli bir özel üye alanı oluşturur:

If Not SomethingHappenedEvent Is Nothing OrElse SomethingHappenedEvent.GetInvocationList.Length = 0 Then
...
End If

Daha fazla bilgi:

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


Neden bunu yapmak istedin? VB'deki bir etkinliğe abone sayısını bilmeniz gereken bir kullanım durumu hayal edemiyorum.
Konrad Rudolph

Belirli durumlarda, olayı başlatırsanız ve işleyici yoksa C # bir istisna atar. VB.Net olmayacak. Dolayısıyla kontrol etme ihtiyacı var.
Joel Coehoorn

2
Bunu abonelere doğrulama hata mesajları veren bir iş nesnesi olayı için kullandım. Doğrulama hatalarının alındığını bilmek için olayın işlenip işlenmediğini kontrol etmek istedim. Aksi takdirde, iş nesnesine bir istisna attırdım.
Technobabble

2
Bu özel üye için başka bir kullanışlı kullanım, Etkinliğin çağrı listesini almaktır. Olayı tüm arayanlara eşzamansız bir şekilde tetiklemek için birkaç durumda kullandım (Dinleyici A'nın olayı Dinleyici B'yi almadan önce değiştirmesini engeller; ayrıca Dinleyici A'nın Dinleyici B'ye iletimi geciktirmesini engeller). Bunu özel veri senkronizasyon senaryolarında ve ayrıca API'lerde çok kullandım.
STW

14

Bir anahtar kelimeyle eşleşecek bir değişken adına ihtiyacınız varsa, onu köşeli parantez içine alın. Başka yerde sınıflandırılmamış. en iyi uygulama olsa da akıllıca kullanılabilir.

Örneğin

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

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

örneğin Yorumlardan örnek (@Pondidum):

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

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

Örnek anahtar kelime olarak "If" kullanmazsanız bu örneğin daha iyi olacağını düşünüyorum.
Sean Gough

4
Başla ve zamanlayıcı Bunu iyi kullanmanın örnekleri olarak akla
gelmeyi bırak

5
Bir sorumluluk reddi beyanı ile işaret ettiği için +1. [Assembly]
STW

5
[Enum], anahtar kelime yerine sınıfı kullanmak için köşeli parantezlere ihtiyaç duyduğunuz bir duruma iyi bir başka örnektir.
Ryan Lundy

13

XML Literals hakkında birkaç cevap var, ancak bu özel durumla ilgili değil:

Aksi takdirde kaçınılması gereken dize değişmezlerini kapatmak için XML Değişmezlerini kullanabilirsiniz. Örneğin, çift tırnak içeren dize değişmez değerleri.

Bunun yerine:

Dim myString = _
    "This string contains ""quotes"" and they're ugly."

Bunu yapabilirsiniz:

Dim myString = _
    <string>This string contains "quotes" and they're nice.</string>.Value

Bu, özellikle CSV ayrıştırması için bir değişmezi test ediyorsanız kullanışlıdır:

Dim csvTestYuck = _
    """Smith"", ""Bob"", ""123 Anywhere St"", ""Los Angeles"", ""CA"""

Dim csvTestMuchBetter = _
    <string>"Smith", "Bob", "123 Anywhere St", "Los Angeles", "CA"</string>.Value

( <string>Elbette etiketi kullanmak zorunda değilsiniz ; istediğiniz herhangi bir etiketi kullanabilirsiniz.)


3
<q>Perl / Ruby'deki kullanıma benzer şekilde iyi bir etiket olacaktır. Her neyse, bu oldukça güzel bir deyim. SEVMEK!
Konrad Rudolph

Ne dahi bir fikir. Teşekkürler
Jeremy

12

DateTime, tarihinizi # ile çevreleyerek başlatılabilir

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

Bu sözdizimiyle birlikte tür çıkarımını da kullanabilirsiniz

Dim independanceDay = #7/4/1776#

Yapıcıyı kullanmaktan çok daha güzel

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

6
Option Strict
On'a sahipseniz hayır

12

Sadece bir satırda 2 satır kodunuz olabilir. dolayısıyla:

Dim x As New Something : x.CallAMethod

whoa ... Bunun sadece sınıf ve mirasla mümkün olduğunu düşündüm
Jason

UnutmaCall (New Something).CallAMethod()
Jonathan Allen

Bu, Apple'daki MS-Basic'ten bir tutucudur] [! Dükkanımda Gotos'u kullandığım için alay edilirdim: - /
HızlıAl

Çoğu zaman bundan kaçınılmalıdır, ancak kullanmayı sevdiğim yerde, satırların gerçekten kısa olduğu ifadelerdir, örneğin, Durum 4: x = 22
dwidel

11

Opsiyonel Parametreler

Opsiyonlar, yeni bir aşırı yük oluşturmaktan çok daha kolaydır, örneğin:

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

1
C # 'ın onları alacağının farkında değildim. Bunlar güzel, ama bunları kullanmak için dikkatli olmak zorunda sadece sen bunları desteklemediği Kodun C # tarafından tüketilen olmayacak olduğun yerde. FxCop / Kod Analizi bunun yerine yöntemi aşırı yüklemenizi söyleyecektir.
STW

... İsteğe bağlı parametreleri üretim kodunun dışında tutarken harika bir kullanım buldum. Sitemde bununla ilgili kısa bir gönderi yazdım: yoooder.com/wordpress/?p=62
STW

2
Ah, bunu çok küçümsüyorum ... Ama Ofis otomasyonu için yararlı
dance2die

9

VB.Net'teki Başlık Durumu eski bir VB6 fxn ile elde edilebilir:

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

1
aynı zamanda textinfo sınıfındadır. içinde hangi ad alanının olduğundan emin değilim. muhtemelen system.text
Shawn

.Net dilinden bağımsız olmanız ve ToTitleCase'i dönüştürmek için Globalization TextInfo sınıfını kullanmanız daha iyi olur. Kodunuzun C # 'a dönüştürülmesi gerekiyorsa, Microsoft gerektiren pek çok küçük pisliğe sahip olacaksınız.VisualBasic
Jeremy

9

Parametreli özellikler

Biraz C # programlama yapıyordum ve VB.Net'te eksik olan ancak burada bahsedilmeyen bir özellik keşfettim.

Bunun nasıl yapılacağına dair bir örnek (c # sınırlamasının yanı sıra) şu adreste görülebilir: C # ... içindeki tipik get set özelliklerini parametrelerle kullanma

Kodu bu yanıttan aldım:

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

Bu ilginç, ancak bunun nerede yararlı olacağından tam olarak emin değilim. myObj.Something ("abc"), bir özellikten çok bir İşleve erişiyormuşsunuz gibi görünür. Bunun sana ne kazandırdığından emin değilim.
mattmc3

Belirsizlikten nefret ederim. Ne olmalı Bir yöntem veya bir özellik. Bazı yeniden düzenleme araçları, her ikisini de belirli durumlarda oluşturmayı öneriyor, bilmiyorlar gibi görünüyor ...
brumScouse
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.