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?
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:
Exception When
Fı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
Enum
sVB'nin gerçek gizli özelliklerinden biri , genişletilmiş işlevselliğe sahip completionlist
kendine benzer Enum
tü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
.
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
.
friend
veya enum: Rule
yerine aynı sınıfı kullanarak bunu elbette önleyebilirsiniz RuleTemplate
.
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*"
VB ilkel bir tür bilir typedef
ile Import
takma 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)
Imports
olmalı. ;-) Her nasılsa, bu hata neredeyse bir yıl boyunca fark edilmedi (ve 28 olumlu oy aldı).
Imports Assert = xUnit.Assert
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>
<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ı.)
Nesne başlatma da burada!
Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}
DirectCast
DirectCast
bir harikadır. Yüzeyde, CType
bir 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. CType
gerç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:
Diğer türler çalışmayacaktır (örneğin, bir'den a'ya kutucuğu Integer
kaldı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 CType
operatörü tercih edin. Kodu çok daha net hale getirir. CType
Öte yandan, yalnızca bu gerçekten amaçlanmışsa, yani bir daraltma CType
operatö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? )
TryCast
zamanlar bahsetmediğim için utanç verici, çünkü ağırlıklı olarak yaygın kullanımla seçmem gereken bir kemiğim vardı CType
.
TryCast
belgelere göre yalnızca başvuru türlerinde çalışır.
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)
:?
, sadece basitleştirilmiş bir sürüm değildir.
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
Select Case True
tam o görünüyor bu değerlendirir sanki her bir Case
beyan 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 . If
Bu bağlamda sözdizimi çok daha nettir ( If...Else If...Else If...Else
).
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!
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 #
(DÜZENLE: Buradan daha fazla bilgi edinin: Her zaman AndAlso ve OrElse operatörlerini kullanmalı mıyım? )
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.
Fi'de bu operatörler arasında farklılıklar vardır:
/
olan Double
\
bir Integer
kalan 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
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:
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
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.
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
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
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")
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
İçe aktarma takma adları da büyük ölçüde bilinmemektedir:
Import winf = System.Windows.Forms
''Later
Dim x as winf.Form
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
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
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.)
<q>
Perl / Ruby'deki kullanıma benzer şekilde iyi bir etiket olacaktır. Her neyse, bu oldukça güzel bir deyim. SEVMEK!
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)
Sadece bir satırda 2 satır kodunuz olabilir. dolayısıyla:
Dim x As New Something : x.CallAMethod
Call (New Something).CallAMethod()
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
VB.Net'teki Başlık Durumu eski bir VB6 fxn ile elde edilebilir:
StrConv(stringToTitleCase, VbStrConv.ProperCase,0) ''0 is localeID
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