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?
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?
Jawaban:
The Exception When
klausul 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
Enum
sSalah satu fitur tersembunyi dari VB adalah completionlist
tag dokumentasi XML yang dapat digunakan untuk membuat Enum
tipe 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
.
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
.
friend
atau dengan menggunakan kelas yang sama dengan enum: Rule
bukan RuleTemplate
.
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*"
VB mengetahui jenis primitif typedef
via Import
alias:
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)
Imports
harus. ;-) Entah bagaimana, kesalahan ini tidak terdeteksi (dan mengumpulkan 28 suara positif) selama hampir setahun penuh.
Imports Assert = xUnit.Assert
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>
<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.)
Inisialisasi objek juga ada di sana!
Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}
DirectCast
DirectCast
adalah keajaiban. Di permukaan, ia bekerja mirip dengan CType
operator yang mengubah objek dari satu jenis ke jenis lainnya. Namun, ini bekerja dengan seperangkat aturan yang jauh lebih ketat. CType
Oleh karena itu, perilaku sebenarnya seringkali tidak jelas dan sama sekali tidak terbukti jenis konversi apa yang dijalankan.
DirectCast
hanya mendukung dua operasi berbeda:
Transmisi lain tidak akan berfungsi (misalnya mencoba membuka kotak Integer
ke 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 DirectCast
bila 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, DirectCast
lebih disukai CType
operator yang lebih umum . Itu membuat kode lebih jelas. CType
, di sisi lain, hanya harus dipanggil jika ini memang dimaksudkan, yaitu ketika CType
operator 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? )
TryCast
saat itu karena saya terutama memiliki tulang untuk dipilih dengan penggunaan yang meluas CType
.
TryCast
hanya berfungsi pada tipe referensi, sesuai dokumentasi.
If
operator bersyarat dan menyatuSaya 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 If
operator 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)
:?
operator Perl , ini bukan hanya versi yang disederhanakan.
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
Select Case True
adalah bahwa hal itu terlihat seolah-olah itu mengevaluasi setiap dari Case
pernyataan 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 If
lebih jelas dalam hal ini ( If...Else If...Else If...Else
).
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!
Pengurai CSV terbaik dan mudah:
Microsoft.VisualBasic.FileIO.TextFieldParser
Dengan menambahkan referensi ke Microsoft.VisualBasic, ini dapat digunakan dalam bahasa .Net lainnya, misalnya C #
(EDIT: Pelajari lebih lanjut di sini: Haruskah saya selalu menggunakan operator AndAlso dan OrElse? )
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.
Di vb ada perbedaan antara operator ini:
/
adalah Double
\
yang Integer
mengabaikan 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
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:
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
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.
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
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
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")
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
Alias impor juga sebagian besar tidak diketahui:
Import winf = System.Windows.Forms
''Later
Dim x as winf.Form
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
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
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.)
<q>
akan menjadi tag yang bagus, mirip dengan penggunaan di Perl / Ruby. Bagaimanapun, itu idiom yang cukup bagus. SUKA!
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)
Anda dapat memiliki 2 baris kode hanya dalam satu baris. karenanya:
Dim x As New Something : x.CallAMethod
Call (New Something).CallAMethod()
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
Kasus Judul di VB.Net dapat dicapai dengan VB6 fxn lama:
StrConv(stringToTitleCase, VbStrConv.ProperCase,0) ''0 is localeID
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