Fitur Tersembunyi dari VB.NET?

121

Saya telah belajar sedikit menelusuri Fitur Tersembunyi C # dan terkejut ketika saya tidak dapat menemukan sesuatu yang serupa untuk VB.NET.

Jadi apa sajakah fitur-fiturnya yang tersembunyi atau kurang dikenal?

Sean Gough
sumber

Jawaban:

128

The Exception Whenklausul sebagian besar tidak diketahui.

Pertimbangkan ini:

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
torial
sumber
9
berguna jika Anda ingin menangkap SQLException tertentu, katakan -2 yang jika saya ingat dengan benar adalah batas waktu jaringan: Tangkap ex sebagai sqlException di mana ex.code = -2
Pondidum
Wow! Saya baru saja membaca ini dan segera menggunakannya untuk menyederhanakan blok coba / tangkap yang baru saya tulis minggu lalu. Saya tidak pernah tahu ini ada.
John M Gant
1
+1 Dan di sinilah blog tim NET CLR menjelaskan mengapa filter pengecualian bermanfaat blogs.msdn.com/clrteam/archive/2009/02/05/…
MarkJ
5
Tidak hanya ini tersembunyi, tetapi juga tidak tersedia di C #.
Cheeso
82

Kustom Enums

Salah satu fitur tersembunyi dari VB adalah completionlisttag dokumentasi XML yang dapat digunakan untuk membuat Enumtipe seperti sendiri dengan fungsionalitas yang diperluas. Fitur ini tidak berfungsi di C #.

Salah satu contoh dari kode terbaru saya:

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

Sekarang, saat menetapkan nilai ke variabel yang dideklarasikan sebagai Rule, IDE menawarkan daftar IntelliSense dari kemungkinan nilai RuleTemplates.

/ EDIT:

Karena ini adalah fitur yang bergantung pada IDE, sulit untuk menunjukkan bagaimana tampilannya saat Anda menggunakannya, tetapi saya hanya akan menggunakan tangkapan layar:

Daftar penyelesaian beraksi http://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

Faktanya, IntelliSense 100% identik dengan apa yang Anda dapatkan saat menggunakan file Enum.

Konrad Rudolph
sumber
Menarik - dapatkah Anda menunjukkan contoh tampilannya saat Anda mengkonsumsinya?
Brian MacKay
Sepertinya seseorang masih dapat membuat aturannya sendiri dengan langsung memanggil konstruktor Aturan? Jika demikian, dan jika Anda ingin menghentikan ini, dapatkah Anda mendeklarasikan konstruktor sebagai "Teman" di perpustakaan Anda?
Joel Coehoorn
Joel, dalam kode contoh saya, saya sengaja tidak melarang ini. Sebaliknya, saya menawarkan kepada pengguna beberapa aturan umum dan mengizinkan pembuatan aturan khusus sendiri. Anda tentu saja dapat mencegah hal ini dengan menandai konstruktor sebagai friendatau dengan menggunakan kelas yang sama dengan enum: Rulebukan RuleTemplate.
Konrad Rudolph
apakah ada suatu tempat dengan daftar penggunaan atribut berguna yang tersembunyi? yang satu ini secara langsung tampak luar biasa, tetapi saya belum yakin di mana saya akan menggunakannya atau apakah itu bisa menyelesaikan keluhan utama dalam beberapa kasus dengan tidak memiliki kemampuan untuk memiliki generik terbatas pada enum.
Maslow
@Maslow: tidak ada atribut yang terlibat di sini. Itu adalah komentar xml.
Joel Coehoorn
49

Pernahkah Anda memperhatikan operator perbandingan Suka?

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

Selengkapnya dari 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*"
Eduardo Molteni
sumber
3
tunggu apa? Itu baru bagiku! Hmm, itu jauh lebih baik daripada alternatif dengan manipulasi string VB.NET: D
STW
.. !! Saya tidak tahu itu meskipun saya mengerjakan beberapa proyek vb.net! Fitur menarik ...
Meta-Knight
woooooooooooooooooooooooow! Terima kasih! itu luar biasa! apakah itu bekerja di ELinq, DLinq juga? bagaimana dengan XLinq?
Shimmy Weitzhandler
@otjoe Hmm? Tidak ada yang 'malas' tentang gumpalan ini.
Josh Lee
Bagaimana kinerjanya, apa yang terjadi di bawah tenda? Apakah ini sinonim dari perpustakaan reg ex?
brumScouse
48

Typedefs

VB mengetahui jenis primitif typedefvia Importalias:

Imports S = System.String

Dim x As S = "Hello"

Ini lebih berguna bila digunakan bersama dengan tipe generik:

Imports StringPair = System.Collections.Generic.KeyValuePair(Of String, String)
Konrad Rudolph
sumber
2
tolong tunjukkan contoh kata Import tidak dikenal di IDE saya.
Shimmy Weitzhandler
5
Importsharus. ;-) Entah bagaimana, kesalahan ini tidak terdeteksi (dan mengumpulkan 28 suara positif) selama hampir setahun penuh.
Konrad Rudolph
Saya selalu bertanya-tanya bagaimana saya bisa membuat "tipe" baru dengan default untuk generik! Keren!
eidylon
3
Impor, Impor, Impor, apa pun! Sheesh, Anda pikir kami membaca posting ini sebelum kami memberi suara positif!
MarkJ
Luar biasa untuk menggunakan xunit dalam tes studio visual yaituImports Assert = xUnit.Assert
wheelibin
45

Oh! dan jangan lupa Literal XML .

Dim contact2 = _
        <contact>
          <name>Patrick Hines</name>
          <%= From p In phoneNumbers2 _
            Select <phone type=<%= p.Type %>><%= p.Number %></phone> _
          %>
        </contact>
Nescio
sumber
Itulah yang ingin saya katakan. Faktanya, saya telah menggunakan literal XML untuk tujuan yang tidak dimaksudkan. Saya menggunakannya untuk menghasilkan Javascript ... swortham.blogspot.com/2009/03/vb-2008.html
Steve Wortham
9
Antara lain, Anda dapat menggunakan Literal XML untuk menghindari pelolosan string yang jelek, misalnya saat Anda menggunakan string yang berisi tanda kutip ganda. Hanya menempatkan string di dalam sebuah XML Literal dan menelepon Nilai, seperti ini: <string>This string contains "quotes" and it's OK.</string>.Value (saya menemukan terutama berguna ketika menulis tes pada parsing file CSV di mana setiap bidang dalam tanda kutip Akan ini. Tidak menyenangkan telah melarikan diri semua orang kutipan dengan tangan di saya garis uji.)
Ryan Lundy
2
@Yralessa: +1, komentar bagus. Faktanya, ini juga cara yang bagus untuk menentukan string multi-baris (memeluk pernyataan SQL, dll.).
Heinzi
Inline XML adalah salah satu fitur VB.NET terburuk yang pernah ada. Fakta yang tidak berdasar.
Berikan Thomas
39

Inisialisasi objek juga ada di sana!

Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}
Nescio
sumber
1
Saya tidak percaya mereka pergi dengan kawat gigi keriting. Kami sudah memiliki pernyataan With .. mereka bisa saja menggunakan kembali sintaks itu.
Sam Axe
2
Saya tahu, itu dibuat hanya untuk menunjukkan kepada Anda bahwa tidak ada polisi di jalan ... lol JK
Shimmy Weitzhandler
4
Inilah yang terjadi jika semua penulis kompilator adalah pemrogram C / C ++ sendiri. Mereka terus menyelipkan sintaks C ke dalam bahasa lain karena mereka tidak dapat membayangkan sesuatu yang lebih baik.
RBarryYoung
38

DirectCast

DirectCastadalah keajaiban. Di permukaan, ia bekerja mirip dengan CTypeoperator yang mengubah objek dari satu jenis ke jenis lainnya. Namun, ini bekerja dengan seperangkat aturan yang jauh lebih ketat. CTypeOleh karena itu, perilaku sebenarnya seringkali tidak jelas dan sama sekali tidak terbukti jenis konversi apa yang dijalankan.

DirectCast hanya mendukung dua operasi berbeda:

  • Membuka kemasan jenis nilai, dan
  • upcasting dalam hierarki kelas.

Transmisi lain tidak akan berfungsi (misalnya mencoba membuka kotak Integerke a Double) dan akan mengakibatkan kesalahan waktu kompilasi / runtime (tergantung pada situasi dan apa yang dapat dideteksi dengan pemeriksaan tipe statis). Oleh karena itu saya menggunakan DirectCastbila memungkinkan, karena ini menangkap maksud saya dengan baik: tergantung pada situasinya, saya ingin membuka kotak nilai dari tipe yang diketahui atau melakukan upcast. Akhir dari cerita.

Menggunakan CType, di sisi lain, membuat pembaca kode bertanya-tanya apa yang sebenarnya dimaksudkan oleh pemrogram karena ia menyelesaikan semua jenis operasi yang berbeda, termasuk memanggil kode yang ditentukan pengguna.

Mengapa ini fitur tersembunyi? Tim VB telah menerbitkan pedoman 1 yang melarang penggunaan DirectCast(meskipun sebenarnya lebih cepat!) Untuk membuat kode lebih seragam. Saya berpendapat bahwa ini adalah pedoman buruk yang harus dibalik: Jika memungkinkan, DirectCastlebih disukai CTypeoperator yang lebih umum . Itu membuat kode lebih jelas. CType, di sisi lain, hanya harus dipanggil jika ini memang dimaksudkan, yaitu ketika CTypeoperator penyempitan (cf. operator overloading ) harus dipanggil.


1) Saya tidak dapat menemukan tautan ke pedoman tetapi saya telah menemukan pendapat Paul Vick (kepala pengembang tim VB):

Di dunia nyata, Anda hampir tidak akan pernah melihat perbedaannya, jadi Anda sebaiknya menggunakan operator konversi yang lebih fleksibel seperti CType, CInt, dll.


(EDIT oleh Zack: Pelajari lebih lanjut di sini: Bagaimana saya harus melakukan cast di VB.NET? )

Konrad Rudolph
sumber
Saya sebenarnya menyukai TryCast () sedikit lebih baik. Itu tidak akan membuat pengecualian, hanya mengembalikan Nothing jika pemerannya gagal. Jika Anda mengharapkan cast sering gagal, ini lebih cepat daripada If TypeOf x Is T ... DirectCast (x, T) dan tentu saja lebih cepat daripada menangkap pengecualian jika DirectCast gagal.
Bob King
6
DirectCast () dan TryCast () sangat berharga bila digunakan dengan benar sebagai pasangan. DirectCast () harus digunakan jika objek yang ditransmisikan selalu diharapkan menjadi jenis target (jika tidak, Anda akan mendapatkan kesalahan, hal yang baik karena ini adalah situasi yang tidak terduga). TryCast () harus digunakan jika objek yang ditransmisikan bisa dari tipe target, atau beberapa tipe target. Menggunakan Satu atau yang lainnya secara eksklusif akan menyebabkan overhead tambahan (jika tipe x adalah y maka siaran langsung (x, y) tidak efisien) atau untuk menghindari kesalahan yang valid (menggunakan TryCast () untuk kasus di mana objek harus selalu menjadi tipe target)
STW
Yoooder: 100% benar. Sayang sekali saya tidak menyebutkannya TryCastsaat itu karena saya terutama memiliki tulang untuk dipilih dengan penggunaan yang meluas CType.
Konrad Rudolph
@Maslow: tentu saja tidak, karena Enum adalah tipe nilai dan TryCasthanya berfungsi pada tipe referensi, sesuai dokumentasi.
Konrad Rudolph
+1: Heh. Saya harus mengakui, saya baru saja membaca ini dan berpikir "Oh ya, DirectCast, bagaimana saya bisa melupakannya?" Dan kemudian saya menggunakannya pada baris kode saya berikutnya (karena saya sangat tidak menyukai CType).
RBarryYoung
37

If operator bersyarat dan menyatu

Saya tidak tahu seberapa tersembunyi Anda menyebutnya, tetapi Iif ([ekspresi], [nilai jika benar], [nilai jika salah]) Sebagai fungsi Objek dapat dihitung.

Itu tidak terlalu tersembunyi seperti sudah usang ! VB 9 memiliki Ifoperator yang jauh lebih baik dan bekerja persis seperti operator bersyarat dan penggabungan C # (tergantung pada apa yang Anda inginkan):

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

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

Diedit untuk menunjukkan contoh lain:

Ini akan bekerja dengan If(), tetapi menyebabkan pengecualian denganIIf()

Dim x = If(b<>0,a/b,0)
Konrad Rudolph
sumber
Bagus, saya tidak tahu ini! Saya baru saja menggunakan IIF kemarin jadi saya akan mengunjungi kembali blok kode itu.
Sean Gough
4
Katakan VS 2005 itu. Tidak semua dari kita dapat bekerja dengan yang terbaru dan terhebat.
Sam Erwin
3
@Lough, omong kosong. Metode ini adalah 100% tipe aman dan mengembalikan objek dengan tipe yang sama seperti argumennya (kedua dan ketiga). Selain itu, harus ada konversi yang melebar di antara argumen, jika tidak akan ada kesalahan kompilasi karena jenisnya tidak cocok.
Konrad Rudolph
1
Ya, IIf () yang bukan tipe aman
Pondidum
2
@ Br.Bill Nyatanya, ini benar - benar setara dengan C dan :?operator Perl , ini bukan hanya versi yang disederhanakan.
Konrad Rudolph
32

Ini bagus. Pernyataan Select Case dalam VB.Net sangat kuat.

Tentu ada standarnya

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

Tapi masih ada lagi ...

Anda dapat melakukan rentang:

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

Dan bahkan lebih ...

Anda dapat (meskipun mungkin bukan ide yang baik) melakukan pemeriksaan boolean pada beberapa variabel:

Select Case True
 Case a = b
    ''//Do X
 Case a = c
    ''//Do Y
 Case b = c
    ''//Do Z
 Case Else
   ''//Exception case
 End Select
torial
sumber
5
Sebenarnya Anda melewatkan beberapa: a) penggunaan "Pilih Kasus Benar" untuk menguji lebih dari satu variabel, b) penggunaan "Kasus A, B, ..." bentuk, dan bahkan c) menerapkan ":" ke dalam- bariskan pernyataan eksekusi dengan klausa kondisi (meskipun banyak yang tidak menyukai ini).
RBarryYoung
6
Harap jangan gunakan Select Case True. Cukup gunakan pernyataan If.
Ryan Lundy
4
Menurut saya Select Case True jauh lebih mudah dibaca daripada pernyataan ifelse raksasa.
dwidel
Masalahnya dengan Select Case Trueadalah bahwa hal itu terlihat seolah-olah itu mengevaluasi setiap dari Casepernyataan dan menjalankan kode untuk masing-masing yang benar. Tetapi pada kenyataannya itu mengevaluasi mereka satu-per-satu dan hanya menjalankan kode untuk yang pertama yang benar. Sintaks untuk Iflebih jelas dalam hal ini ( If...Else If...Else If...Else).
Ryan Lundy
31

Salah satu penghemat waktu utama yang saya gunakan sepanjang waktu adalah kata kunci With :

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

Saya hanya tidak suka mengetik lebih dari yang seharusnya!

Jasha87
sumber
Tapi itu juga membuat beberapa bug tersembunyi, terutama bila Anda memiliki With di dalam
Varun Mahajan
2
Saya bahkan tidak tahu Anda bisa memasang With baru dalam With yang sudah ada. Itu ceroboh!
Bob King
2Bob: ini tidak ceroboh, saya sarankan .. ini hanya konstruksi bahasa untuk digunakan dengan hati-hati. Untuk menyetel banyak properti dalam baris yang berurutan, itu bagus, tetapi menemukan .Foo acak dalam bagian kode yang kompleks dan kemudian harus mencari pernyataan With x baris di atas bukanlah penggunaan fitur yang baik.
ChrisA
2
Ingin C # memiliki ini? Atau apakah saya sudah tertidur dan apakah itu jawaban fitur tersembunyi di C # ...? ;-)
peSHIr
1
@Boo: Anda benar tetapi masih menjengkelkan karena Anda tidak dapat menambahkannya ke daftar Pantauan.
Meta-Knight
31

Pengurai CSV terbaik dan mudah:

Microsoft.VisualBasic.FileIO.TextFieldParser

Dengan menambahkan referensi ke Microsoft.VisualBasic, ini dapat digunakan dalam bahasa .Net lainnya, misalnya C #

cjk
sumber
5
+1 Aneh bagaimana orang-orang C # lari ke FileHelpers tanpa pernah mempertimbangkan ini. Saya yakin FileHelpers sangat bagus, tetapi ini adalah ketergantungan eksternal.
MarkJ
@MarkJ Saya kira itu karena ketidaktahuan
Nathan Koop
Saya mencari tahu di Google untuk mencoba menemukan kelas ini dan tidak pernah melakukannya, terima kasih telah mengobrak-abriknya!
pingoo
26
  • AndAlso / OrElse operator logika

(EDIT: Pelajari lebih lanjut di sini: Haruskah saya selalu menggunakan operator AndAlso dan OrElse? )

Joel Coehoorn
sumber
Saya tidak akan menyebutnya tersembunyi sama sekali, Jika Kontak Bukan Apa-apa Dan Juga Kontak.ContactId> 0 Kemudian Lakukan, Jika Anda akan menggunakan Dan Anda akan mendapat pengecualian.
Shimmy Weitzhandler
25

Anggota statis dalam metode.

Sebagai contoh:

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

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

Dalam fungsi di atas, ekspresi reguler pola hanya akan dibuat satu kali tidak peduli berapa kali fungsi tersebut dipanggil.

Penggunaan lain adalah untuk menyimpan contoh "acak" di sekitar:

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

    Return r.Next()
End Function 

Juga, ini tidak sama dengan hanya mendeklarasikannya sebagai anggota Bersama kelas; item yang dideklarasikan dengan cara ini dijamin juga aman untuk thread. Tidak masalah dalam skenario ini karena ekspresi tidak akan pernah berubah, tetapi ada orang lain yang mungkin melakukannya.

Joel Coehoorn
sumber
1
Salah satu kegunaannya adalah untuk menyimpan penghitung yang akan bertambah setiap kali metode dipanggil. Jika variabel ditandai Statis, variabel tidak akan diinisialisasi ulang pada setiap pemanggilan metode; itu hanya akan diinisialisasi pada panggilan pertama, dan setelah itu akan mempertahankan nilainya.
Ryan Lundy
Inilah alasan mengapa anggota kelas statis dinamai "dibagikan" di VB.NET
Enrico Campidoglio
Statis adalah bentuk yang buruk di VB.NET bahkan lebih dari itu di VB klasik. Variabel statis harus dihindari kapanpun dan dimanapun memungkinkan.
Sam Axe
6
@Boo - itu cukup menyapu. Apa pembenaran Anda? Saya pikir variabel statis berguna.
MarkJ
4
Statis, digunakan seperti dalam contoh di atas, memungkinkan bentuk enkapsulasi yang unik: variabel tingkat kelas yang memiliki cakupan tingkat metode. Tanpanya, Anda harus membuat variabel tingkat kelas yang dapat diakses oleh semua anggota kelas, bahkan jika Anda hanya menggunakannya dalam satu metode.
Ryan Lundy
25

Di vb ada perbedaan antara operator ini:

/adalah Double
\yang Integermengabaikan sisanya

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
Shimmy
sumber
1
Saya mempelajari ini dengan cara yang sulit ketika mencoba menemukan jarum dalam jutaan baris kode. divisi reguler versus integer. tip bagus!
Jason Irwin
23

Saya sangat menyukai Namespace "Saya" yang diperkenalkan pada Visual Basic 2005. Saya adalah jalan pintas ke beberapa grup informasi dan fungsionalitas. Ini memberikan akses cepat dan intuitif ke jenis informasi berikut:

  • My.Computer : Akses ke informasi yang terkait dengan komputer seperti sistem file, jaringan, perangkat, informasi sistem, dll. Ini menyediakan akses ke sejumlah sumber daya yang sangat penting termasuk My.Computer.Network, My.Computer.FileSystem, dan My .Komputer.Printer.
  • Aplikasi Saya : Akses ke informasi yang terkait dengan aplikasi tertentu seperti nama, versi, direktori saat ini, dll.
  • My.User : Akses ke informasi yang terkait dengan pengguna terotentikasi saat ini.
  • My.Resources : Akses ke sumber daya yang digunakan oleh aplikasi yang berada di file sumber daya dengan cara yang sangat diketik.
  • My.Settings : Akses ke pengaturan konfigurasi aplikasi dengan cara yang sangat diketik.
percikan
sumber
Ini sangat bagus dan setiap pria vb.net di luar sana harus tahu hal-hal di namespace saya, ini sangat berguna.
dr. jahat
Saya. * FTW :).
dr. kejahatan
3
Ini agak berguna, tapi aku benci nama bodoh itu. Mengingatkan saya pada secretgeek.net/refactvb.asp
MarkJ
23

Acara Kustom

Meskipun jarang berguna, penanganan acara bisa sangat disesuaikan:

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

Ini kemudian dapat diuji dengan cara berikut:

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
Konrad Rudolph
sumber
sepertinya keren, tetapi jika saya membutuhkan ini, saya pikir saya akan melakukan sesuatu yang salah ;-). Sepertinya itu bertentangan dengan prinsip KISS.
chrissie1
4
Ini benar-benar berguna ketika Anda ingin memastikan setiap sink mendapatkan acara bahkan jika satu atau lebih mengeluarkan pengecualian.
Jonathan Allen
Nilai lain (saya baru saja membacanya di situs MSDN) adalah jika kelas Anda melempar banyak acara, Anda dapat memaksanya untuk menggunakan tabel / kamus hash sebagai wadah, daripada mendeklarasikan bidang untuk setiap acara. msdn.microsoft.com/en-us/library/8627sbea(VS.71).aspx
torial
Keren. Saya pikir ini salah satu fitur yang membedakan C # dan VB.NET (seperti dalam satu kaleng, tetapi yang lain tidak memiliki sintaks untuk itu). Senang setidaknya tahu saya salah dalam hal ini.
peSHIr
21

Saya baru saja menemukan artikel yang membahas tentang "!" operator, juga dikenal sebagai "operator pencarian kamus". Berikut kutipan dari artikel di: http://panopticoncentral.net/articles/902.aspx

Nama teknis untuk! operator adalah "operator pencarian kamus". Kamus adalah jenis koleksi apa pun yang diindeks dengan kunci daripada angka, seperti cara entri dalam kamus bahasa Inggris diindeks oleh kata yang Anda inginkan definisinya. Contoh paling umum dari tipe kamus adalah System.Collections.Hashtable, yang memungkinkan Anda untuk menambahkan pasangan (kunci, nilai) ke dalam hashtable dan kemudian mengambil nilai menggunakan kunci. Misalnya, kode berikut menambahkan tiga entri ke hashtable, dan mencari salah satunya menggunakan kunci "Pork".

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

The! operator dapat digunakan untuk mencari nilai dari jenis kamus apa pun yang mengindeks nilainya menggunakan string. Pengenal setelah! digunakan sebagai kunci dalam operasi pencarian. Jadi kode di atas malah bisa ditulis:

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

Contoh kedua benar-benar setara dengan yang pertama, tetapi terlihat jauh lebih bagus, setidaknya di mata saya. Saya menemukan bahwa ada banyak tempat di mana! dapat digunakan, terutama dalam hal XML dan web, di mana hanya ada banyak koleksi yang diindeks oleh string. Salah satu batasan yang disayangkan adalah hal yang mengikuti! masih harus menjadi pengenal yang valid, jadi jika string yang ingin Anda gunakan sebagai kunci memiliki beberapa karakter pengenal yang tidak valid di dalamnya, Anda tidak dapat menggunakan! operator. (Anda tidak dapat, misalnya, mengatakan "Tabel! AB $ CD = 5" karena $ tidak legal dalam pengidentifikasi.) Dalam VB6 dan sebelumnya, Anda dapat menggunakan tanda kurung untuk menghindari pengidentifikasi yang tidak valid (yaitu "Tabel! [AB $ CD] "), tetapi saat kami mulai menggunakan tanda kurung untuk melepaskan kata kunci, kami kehilangan kemampuan untuk melakukannya. Umumnya,

Untuk mendapatkan yang benar-benar teknis, x! Y berfungsi jika x memiliki properti default yang menggunakan String atau Objek sebagai parameter. Dalam hal ini, x! Y diubah menjadi x.DefaultProperty ("y"). Catatan samping yang menarik adalah bahwa ada aturan khusus dalam tata bahasa leksikal untuk membuat ini semua berfungsi. The! karakter juga digunakan sebagai karakter tipe dalam bahasa, dan karakter tipe dimakan sebelum operator. Jadi tanpa aturan khusus, x! Y akan dipindai sebagai "x! Y" bukan "x! Y". Untungnya, karena tidak ada tempat dalam bahasa di mana dua pengenal berturut-turut valid, kami baru saja memperkenalkan aturan bahwa jika karakter berikutnya setelah! adalah awal pengenal, kami menganggap! menjadi operator dan bukan tipe karakter.

torial
sumber
11
Itulah salah satu fitur yang saya gunakan lalu sengaja saya lupakan. Ini menghemat beberapa penekanan tombol tetapi mengacaukan penyorotan kode dan keterbacaan saya. lupa lagi kan .... SEKARANG
STW
3
Menarik, tapi tidak terlalu berguna. Apakah ini jenis hal yang dikerjakan oleh tim VB alih-alih menambahkan fitur yang hilang seperti kata kunci hasil? : P
Meta-Knight
5
Fitur ini dibawa untuk kompatibilitas mundur dari VB3 (AFAIK)
Eduardo Molteni
1
apakah kelas-kelas yang menerapkan indeks kunci memiliki antarmuka umum yang mereka warisi? seperti IKeyed dengan cara yang sama wadah terindeks integer menerapkan IENumberable?
Maslow
2
Fitur ini juga bekerja dengan DataRows (mis. Dr! ID) yang SANGAT berguna di LINQ ke DataSets.
Paul
19

Ini built-in, dan keuntungan pasti atas C #. Kemampuan untuk mengimplementasikan Metode antarmuka tanpa harus menggunakan nama yang sama.

Seperti:

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

End Sub
torial
sumber
Saya yakin Anda bisa melakukan sesuatu seperti ini di C #. Di VB.NET itu hanya dipaksa, dan di C # itu opsional?
Jesper Blad Jen
5
Anda juga dapat membuat sub-privat, yang merupakan cara terbaik untuk menyembunyikan hal-hal seperti panggilan ke versi antarmuka non-generik yang tidak digunakan lagi.
Craig Gidney
3
Ini bisa menjadi ide yang bagus. Contoh klasiknya adalah jika Anda menginginkan metode Tutup Publik yang juga bertindak sebagai implementasi Buang untuk IDisposable.
MarkJ
1
Itu juga sangat berguna jika Anda kebetulan mengimplementasikan dua antarmuka yang berbagi nama metode.
Eric Nicholson
Saya telah melihat ini dan selalu berharap saya tidak melihatnya. Seharusnya tidak diizinkan.
FastAl
17

Memaksa ByVal

Di VB, jika Anda membungkus argumen Anda dalam satu set tanda kurung tambahan, Anda dapat mengganti deklarasi ByRef dari metode tersebut dan mengubahnya menjadi ByVal. Misalnya, kode berikut menghasilkan 4, 5, 5, bukan 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

Lihat Argumen Tidak Dimodifikasi oleh Panggilan Prosedur - Variabel yang Mendasari

Chris Haas
sumber
6
Ya ampun ... itu fitur yang luar biasa, meskipun saya rasa saya tidak akan tahu apa yang dilakukannya jika saya membacanya di kode orang lain. Jika Anda harus mengomentarinya hanya untuk mengetahui apa yang dilakukannya, Anda mungkin juga telah membuat variabel throw away sebagai gantinya.
mattmc3
7
Ini sebenarnya adalah efek samping dari penggunaan tanda kurung - Tanda kurung membuat nilai temp dari apa yang ada di dalamnya, meskipun hanya satu item. Efek ini MEMBUNUH SAYA di vb6 - Panggilan sub tidak mengambil tanda kurung, tetapi saya yang berasal dari C secara naluriah memasukkan tanda kurung. 6.0 meledak pada beberapa parameter, tetapi untuk satu parameter sub, dengan senang hati melewati nilai temp dan DITOLAK untuk menghormati saya 'byref'. Terjadi kira-kira setiap 3 tahun, kira-kira waktu yang saya butuhkan untuk melupakan kejadian terakhir.
FastAl
16

Meneruskan parameter dengan nama dan, jadi menyusun ulang mereka

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

    'Do stuff

End function

Pemakaian:

Module Module1

    Sub Main()

        MyFunc() 'No params specified

    End Sub

End Module

Dapat juga dipanggil menggunakan spesifikasi parameter ": =" dalam urutan apa pun:

MyFunc(displayOrder:=10, msg:="mystring")
kaya
sumber
Wow, ini sangat keren! Saya melihat ini saat menggunakan Layanan Web, dll tetapi saya tidak tahu Anda dapat melakukan ini dengan metode normal apa pun.
RichC
2
Jelas alat yang sangat berguna ketika Anda menemukan metode yang membutuhkan terlalu banyak argumen. Saya mencoba memberi nama setiap parameter dan memberi nama: = nilai pada barisnya sendiri. Jauh lebih intuitif dan bersih untuk metode yang mengambil> 5 (aturan praktis saya) parameter.
STW
Sangat berguna untuk otomatisasi Office, di mana Anda harus mengatasi metode dengan lusinan argumen opsional.
MarkJ
1
Yang juga keren adalah Anda bisa mencampur keduanya: mulai dengan menentukan parameter yang diperlukan secara berurutan, lalu beralih ke parameter bernama untuk argumen opsional!
RBarryYoung
15

Pernyataan Using baru pada VB 8, C # memilikinya sejak awal. Ini panggilan membuang secara otomatis untuk Anda.

Misalnya

Using lockThis as New MyLocker(objToLock)

End Using
torial
sumber
23
Perlu dicatat (hanya karena saya lupa setidaknya dua kali) bahwa Anda dapat memiliki satu pernyataan Using membungkus beberapa objek Disposable. Sintaksnya adalah "Menggunakan objA sebagai objek baru, objB sebagai objek baru ...." Ini jauh lebih bersih daripada membuat beberapa pernyataan Using.
STW
Pasti salah satu favorit saya juga.
Sam Axe
14

Alias ​​impor juga sebagian besar tidak diketahui:

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form
torial
sumber
1
Saya pikir kami memiliki ide yang sama.
chrissie1
3
@Boo - berikut adalah contoh sederhana di mana alias impor tidak jahat. stackoverflow.com/questions/92869/…
torial
Oke - jelas ada cara untuk penyalahgunaan, tetapi terlepas dari kata-kata kasar @ torial, ini adalah fitur yang bagus. Setiap kali saya menyertakan System.Text.RegularExpressions saya berisiko mengalami benturan nama dengan kelas "Grup" karena itu adalah nama kelas yang umum. Alias ​​memungkinkan Anda menghindari keharusan untuk sepenuhnya memenuhi syarat kelas ambigu yang merupakan penghemat waktu yang sangat besar dan benar-benar meningkatkan keterbacaan saat digunakan dengan benar. Fiturnya bagus, tetapi contoh spesifik Anda memang mengundang ejekan - maaf untuk mengatakannya.
mattmc3
14

Pertimbangkan deklarasi acara berikut

Public Event SomethingHappened As EventHandler

Di C #, Anda dapat memeriksa pelanggan acara dengan menggunakan sintaks berikut:

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

Namun, kompiler VB.NET tidak mendukung ini. Ini benar-benar membuat bidang anggota pribadi tersembunyi yang tidak terlihat di IntelliSense:

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

Informasi Lebih Lanjut:

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

Technobabble
sumber
Mengapa Anda ingin melakukan itu? Saya tidak bisa membayangkan kasus penggunaan di mana Anda perlu mengetahui jumlah pelanggan sebuah acara di VB.
Konrad Rudolph
Dalam keadaan tertentu, C # membuat pengecualian jika Anda menaikkan acara dan tidak ada penangan. VB.Net tidak akan. Oleh karena itu perlu dilakukan pengecekan.
Joel Coehoorn
2
Saya menggunakan ini untuk acara objek bisnis yang memunculkan pesan kesalahan validasi ke pelanggan. Saya ingin memeriksa untuk melihat apakah acara tersebut ditangani sehingga saya tahu kesalahan validasi sedang diterima. Kalau tidak, saya meminta objek bisnis untuk mengeluarkan pengecualian.
Technobabble
2
Penggunaan praktis lainnya untuk anggota pribadi ini adalah untuk mendapatkan daftar permintaan Acara. Saya telah menggunakannya dalam beberapa kasus untuk mengaktifkan peristiwa secara asinkron ke semua pemanggil (mencegah Pendengar A mengubah peristiwa sebelum Pendengar B menerimanya; juga mencegah Pendengar A menunda pengiriman ke Pendengar B). Saya sering menggunakan ini dalam skenario sinkronisasi data khusus, dan juga di API.
STW
14

Jika Anda memerlukan nama variabel yang cocok dengan kata kunci, apit dengan tanda kurung. Tidak nec. praktik terbaik - tetapi dapat digunakan dengan bijak.

misalnya

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

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

misalnya Contoh dari komentar (@Pondidum):

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

Public Sub [Stop]()
''...
End Sub
torial
sumber
Saya rasa contoh ini akan lebih baik jika Anda tidak menggunakan "If" sebagai contoh kata kunci.
Sean Gough
4
pengatur waktu Mulai dan pengatur waktu Berhenti memikirkan sebagai contoh penggunaan yang baik dari ini
Pondidum
5
1 untuk menunjukkannya dengan penafian. Ada beberapa kelas framework yang memerlukan ini untuk menyelesaikan dengan benar, seperti [Assembly]
STW
5
[Enum] adalah contoh bagus lainnya dari kasus di mana Anda memerlukan tanda kurung untuk menggunakan kelas, bukan kata kunci.
Ryan Lundy
13

Ada beberapa jawaban tentang Literal XML, tetapi bukan tentang kasus khusus ini:

Anda bisa menggunakan Literal XML untuk menyertakan literal string yang seharusnya di-escape. String literal yang berisi tanda kutip ganda, misalnya.

Daripada ini:

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

Kamu bisa melakukan ini:

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

Ini sangat berguna jika Anda menguji literal untuk penguraian CSV:

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

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

(Anda tidak harus menggunakan <string>tag, tentu saja; Anda dapat menggunakan tag apa pun yang Anda suka.)

Ryan Lundy
sumber
3
<q>akan menjadi tag yang bagus, mirip dengan penggunaan di Perl / Ruby. Bagaimanapun, itu idiom yang cukup bagus. SUKA!
Konrad Rudolph
Ide yang sangat jenius. Terima kasih
Jeremy
12

DateTime dapat diinisialisasi dengan mengelilingi tanggal Anda dengan #

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

Anda juga dapat menggunakan inferensi tipe bersama dengan sintaks ini

Dim independanceDay = #7/4/1776#

Itu jauh lebih bagus daripada menggunakan konstruktor

Dim independanceDay as DateTime = New DateTime(1776, 7, 4)
danlash
sumber
6
Tidak jika Anda memiliki Option Strict On
danlash
12

Anda dapat memiliki 2 baris kode hanya dalam satu baris. karenanya:

Dim x As New Something : x.CallAMethod
Parsa
sumber
whoa ... saya pikir ini hanya mungkin w / kelas dan warisan
Jason
Jangan lupaCall (New Something).CallAMethod()
Jonathan Allen
Ini adalah pegangan dari MS-Basic di Apple] [! Di toko saya, saya akan diejek karena menggunakan Gotos: - /
FastAl
Sebagian besar waktu ini harus dihindari tetapi di mana saya suka menggunakannya adalah dalam pernyataan kasus di mana garis-garisnya sangat pendek misalnya Kasus 4: x = 22
dwidel
11

Parameter Opsional

Opsional jauh lebih mudah daripada membuat overload baru, seperti:

Function CloseTheSystem(Optional ByVal msg AS String = "Shutting down the system...")
   Console.Writeline(msg)
   ''//do stuff
End Function
dr. jahat
sumber
1
Saya tidak tahu bahwa C # akan mendapatkannya. Mereka bagus, tapi Anda harus berhati-hati untuk menggunakannya hanya jika Anda yakin kode tidak akan dikonsumsi oleh C # karena tidak mendukungnya. FxCop / Code Analysis akan memberi tahu Anda untuk membebani metode sebagai gantinya.
STW
... Saya baru saja menemukan kegunaan yang bagus untuk parameter Opsional, sambil tetap menjauhkannya dari kode produksi. Saya menulis posting singkat tentang hal itu di situs saya: yoooder.com/wordpress/?p=62
STW
2
Ah, saya sangat membenci ini ... Tapi berguna untuk otomatisasi Kantor
dance2die
9

Kasus Judul di VB.Net dapat dicapai dengan VB6 fxn lama:

StrConv(stringToTitleCase, VbStrConv.ProperCase,0) ''0 is localeID
torial
sumber
1
itu juga di kelas textinfo. tidak yakin namespace apa yang ada di. mungkin system.text
Shawn
Anda lebih baik menggunakan bahasa .net netral dan menggunakan kelas Globalization TextInfo untuk mengubah ToTitleCase. Jika kode Anda perlu diubah ke C # Anda akan memiliki banyak kejahatan kecil yang membutuhkan Microsoft.VisualBasic
Jeremy
9

Properti dengan parameter

Saya telah melakukan beberapa pemrograman C #, dan menemukan fitur yang hilang dari VB.Net, tetapi tidak disebutkan di sini.

Contoh bagaimana melakukan ini (serta batasan c #) dapat dilihat di: Menggunakan properti get set tipikal di C # ... dengan parameter

Saya telah mengutip kode dari jawaban itu:

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
torial
sumber
Ini menarik, tetapi saya tidak sepenuhnya yakin di mana ini akan berguna. myObj.Something ("abc") terlihat lebih seperti Anda mengakses Fungsi daripada properti. Tidak yakin apa yang membeli Anda.
mattmc3
Saya benci ambiguitas. Apa yang seharusnya. Metode, atau properti. Beberapa alat refactoring menyarankan untuk membuat keduanya dalam situasi tertentu juga, sepertinya mereka bahkan tidak tahu ...
brumScouse