C#の非表示の機能を使用してかなりのブラウジングを学びましたが、VB.NETに似たものを見つけることができなかったときは驚きました。
それで、その隠されたまたはあまり知られていない機能のいくつかは何ですか?
C#の非表示の機能を使用してかなりのブラウジングを学びましたが、VB.NETに似たものを見つけることができなかったときは驚きました。
それで、その隠されたまたはあまり知られていない機能のいくつかは何ですか?
回答:
このException When条項はほとんど不明です。
このことを考慮:
Public Sub Login(host as string, user as String, password as string, _
                            Optional bRetry as Boolean = False)
Try
   ssh.Connect(host, user, password)
Catch ex as TimeoutException When Not bRetry
   ''//Try again, but only once.
   Login(host, user, password, True)
Catch ex as TimeoutException
   ''//Log exception
End Try
End Sub
              EnumsVBの本当の隠し機能の1つは、拡張機能を備えたcompletionlist独自のEnumタイプを作成するために使用できるXMLドキュメントタグです。ただし、この機能はC#では機能しません。
私の最近のコードからの一例:
'
''' <completionlist cref="RuleTemplates"/>
Public Class Rule
    Private ReadOnly m_Expression As String
    Private ReadOnly m_Options As RegexOptions
    Public Sub New(ByVal expression As String)
        Me.New(expression, RegexOptions.None)
    End Sub
    Public Sub New(ByVal expression As String, ByVal options As RegexOptions)
        m_Expression = expression
        m_options = options
    End Sub
    Public ReadOnly Property Expression() As String
        Get
            Return m_Expression
        End Get
    End Property
    Public ReadOnly Property Options() As RegexOptions
        Get
            Return m_Options
        End Get
    End Property
End Class
Public NotInheritable Class RuleTemplates
    Public Shared ReadOnly Whitespace As New Rule("\s+")
    Public Shared ReadOnly Identifier As New Rule("\w+")
    Public Shared ReadOnly [String] As New Rule("""([^""]|"""")*""")
End Class
現在、として宣言された変数に値を割り当てるRuleと、IDEはからの可能な値のIntelliSenseリストを提供しますRuleTemplates。
これはIDEに依存する機能であるため、使用時にどのように見えるかを示すのは困難ですが、ここではスクリーンショットを使用します。
実際の完了リストhttp://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png
実際、IntelliSenseは、を使用した場合に得られるものと100%同一ですEnum。
friendか、のRule代わりにenum:と同じクラスを使用することで、これを防ぐことができRuleTemplateます。
                    Like比較演算子に気づきましたか?
    Dim b As Boolean = "file.txt" Like "*.txt"
MSDNの詳細
Dim testCheck As Boolean
' The following statement returns True (does "F" satisfy "F"?)'
testCheck = "F" Like "F"
' The following statement returns False for Option Compare Binary'
'    and True for Option Compare Text (does "F" satisfy "f"?)'
testCheck = "F" Like "f"
' The following statement returns False (does "F" satisfy "FFF"?)'
testCheck = "F" Like "FFF"
' The following statement returns True (does "aBBBa" have an "a" at the'
'    beginning, an "a" at the end, and any number of characters in '
'    between?)'
testCheck = "aBBBa" Like "a*a"
' The following statement returns True (does "F" occur in the set of'
'    characters from "A" through "Z"?)'
testCheck = "F" Like "[A-Z]"
' The following statement returns False (does "F" NOT occur in the '
'    set of characters from "A" through "Z"?)'
testCheck = "F" Like "[!A-Z]"
' The following statement returns True (does "a2a" begin and end with'
'    an "a" and have any single-digit number in between?)'
testCheck = "a2a" Like "a#a"
' The following statement returns True (does "aM5b" begin with an "a",'
'    followed by any character from the set "L" through "P", followed'
'    by any single-digit number, and end with any character NOT in'
'    the character set "c" through "e"?)'
testCheck = "aM5b" Like "a[L-P]#[!c-e]"
' The following statement returns True (does "BAT123khg" begin with a'
'    "B", followed by any single character, followed by a "T", and end'
'    with zero or more characters of any type?)'
testCheck = "BAT123khg" Like "B?T*"
' The following statement returns False (does "CAT123khg" begin with'
'    a "B", followed by any single character, followed by a "T", and'
'    end with zero or more characters of any type?)'
testCheck = "CAT123khg" Like "B?T*"
              VBは、プリミティブな種類のtypedefvia Importエイリアスを知っています。
Imports S = System.String
Dim x As S = "Hello"
これは、ジェネリック型と組み合わせて使用するとさらに便利です。
Imports StringPair = System.Collections.Generic.KeyValuePair(Of String, String)
              Importsそのはず。;-)どういうわけか、このエラーはほぼ1年間検出されずに(そして28の賛成投票を獲得して)います。
                    Imports Assert = xUnit.Assert
                    ああ!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   、すべてのフィールドが引用符にあったCSVファイルを解析する上でテストを書くとき、(私はこれは特に便利見つかったことがない。ない私の手ですべてのそれらの引用符をエスケープする楽しされていますテストライン。)
                    オブジェクトの初期化もそこにあります!
Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}
              DirectCastDirectCast驚異です。表面上はCType、オブジェクトをあるタイプから別のタイプに変換するという点で、オペレーターと同様に機能します。ただし、これはより厳密なルールのセットによって機能します。CTypeしたがって、の実際の動作は不透明であることが多く、どの種類の変換が実行されるかはまったく明らかではありません。
DirectCast は、2つの異なる操作のみをサポートします。
他のキャストは機能せず(例:をにボックス化解除しようとIntegerするDouble)、コンパイル時/実行時エラーが発生します(状況と静的型チェックで検出できるものによって異なります)。したがってDirectCast、可能な限り使用します。これは私の意図を最もよく表しています。状況に応じて、既知のタイプの値のボックスを解除するか、アップキャストを実行します。物語の終わり。
CType一方、を使用すると、ユーザーが定義したコードの呼び出しなど、さまざまな種類の操作に解決されるため、コードの読者はプログラマーが実際に何を意図したのか疑問に思います。
なぜこれが隠し機能なのですか?VBチームは、コードをより均一にするために(実際にはより高速ですが)の使用を推奨しないガイドライン1を公開しましたDirectCast。これは悪いガイドラインであると私は主張します。可能な限り、DirectCastより一般的なCType演算子よりも有利にしてください。コードがより明確になります。CType一方、これが本当に意図されている場合、つまり、ナローイングCType演算子(cf. operator overloading)を呼び出す必要がある場合にのみ呼び出す必要があります。
1)ガイドラインへのリンクを思い付くことができませんが、Paul Vickがそれを引き受けていることがわかりました(VBチームのチーフ開発者):
実際には、違いに気付くことはほとんどないので、CTypeやCIntなどのより柔軟な変換演算子を使用することもできます。
(ザックによる編集:詳細はこちら:VB.NETでキャストするにはどうすればよいですか?)
TryCast私が主にを使用して選択する骨を持っているので、それは私が当時言及しなかったのは残念ですCType。
                    TryCast、ドキュメントに従って参照型でのみ機能するため、もちろんそうではありません。
                    If 条件付き合体演算子どのように非表示にしたかわかりませんが、Iif([式]、[trueの場合の値]、[falseの場合の値])As Object関数は数えることができます。
非推奨のように隠されているわけではありません。VB 9には、Ifはるかに優れた演算子があり、C#の条件付きおよび合体演算子とまったく同じように機能します(目的に応じて異なります)。
Dim x = If(a = b, c, d)
Dim hello As String = Nothing
Dim y = If(hello, "World")
別の例を示すように編集:
これはで機能しIf()ますが、IIf()
Dim x = If(b<>0,a/b,0)
              :?、単純なバージョンではありません。
                    これはいいですね。VB.Net内のSelect Caseステートメントは非常に強力です。
確かに標準があります
Select Case Role
  Case "Admin"
         ''//Do X
  Case "Tester"
         ''//Do Y
  Case "Developer"
         ''//Do Z
  Case Else
       ''//Exception case
End Select
しかし、もっとあります...
あなたは範囲を行うことができます:
Select Case Amount
 Case Is < 0
    ''//What!!
 Case 0 To 15
   Shipping = 2.0
 Case 16 To 59
    Shipping = 5.87
 Case Is > 59
    Shipping = 12.50
 Case Else
    Shipping = 9.99
 End Select
そしてさらに...
あなたは(良い考えではないかもしれませんが)複数の変数に対してブールチェックを行うことができます:
Select Case True
 Case a = b
    ''//Do X
 Case a = c
    ''//Do Y
 Case b = c
    ''//Do Z
 Case Else
   ''//Exception case
 End Select
              Select Case Trueに見えることです。しかし、実際には1つずつ評価され、真の最初のコードのみが実行されます。の構文は、この点ではるかに明確です()。CaseIfIf...Else If...Else If...Else
                    私がいつも使用している主要な時間節約機能の1つはWithキーワードです。
With ReallyLongClassName
    .Property1 = Value1
    .Property2 = Value2
    ...
End With
必要以上にタイプするのは好きではありません!
最高で簡単なCSVパーサー:
Microsoft.VisualBasic.FileIO.TextFieldParser
Microsoft.VisualBasicへの参照を追加することにより、これを他の.Net言語、たとえばC#で使用できます。
(編集:詳細はこちら:常にAndAlsoおよびOrElse演算子を使用する必要がありますか?)
メソッドの静的メンバー。
例えば:
Function CleanString(byval input As String) As String
    Static pattern As New RegEx("...")
    return pattern.Replace(input, "")
End Function
上記の関数では、関数が何度呼び出されても、パターン正規表現は一度だけ作成されます。
別の用途は、「ランダム」のインスタンスを保持することです。
Function GetNextRandom() As Integer
    Static r As New Random(getSeed())
    Return r.Next()
End Function 
また、これは単にクラスの共有メンバーとして宣言するのと同じではありません。この方法で宣言されたアイテムは、スレッドセーフであることが保証されています。このシナリオでは式は決して変わらないので問題ではありませんが、変化する可能性のある他のシナリオもあります。
VBでは、これらの演算子に違いがあります。
/されDouble
\ているInteger残りを無視
Sub Main()
    Dim x = 9 / 5  
    Dim y = 9 \ 5  
    Console.WriteLine("item x of '{0}' equals to {1}", x.GetType.FullName, x)
    Console.WriteLine("item y of '{0}' equals to {1}", y.GetType.FullName, y)
    'Results:
    'item x of 'System.Double' equals to 1.8
    'item y of 'System.Int32' equals to 1
End Sub
              私は本当にのように、「私」名前空間のVisual Basic 2005で導入された私の情報と機能のいくつかのグループへのショートカットです。次のタイプの情報にすばやく直感的にアクセスできます。
あまり役に立ちませんが、イベント処理は大幅にカスタマイズできます。
Public Class ApplePie
    Private ReadOnly m_BakedEvent As New List(Of EventHandler)()
    Custom Event Baked As EventHandler
        AddHandler(ByVal value As EventHandler)
            Console.WriteLine("Adding a new subscriber: {0}", value.Method)
            m_BakedEvent.Add(value)
        End AddHandler
        RemoveHandler(ByVal value As EventHandler)
            Console.WriteLine("Removing subscriber: {0}", value.Method)
            m_BakedEvent.Remove(value)
        End RemoveHandler
        RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
            Console.WriteLine("{0} is raising an event.", sender)
            For Each ev In m_BakedEvent
                ev.Invoke(sender, e)
            Next
        End RaiseEvent
    End Event
    Public Sub Bake()
        ''// 1. Add ingredients
        ''// 2. Stir
        ''// 3. Put into oven (heated, not pre-heated!)
        ''// 4. Bake
        RaiseEvent Baked(Me, EventArgs.Empty)
        ''// 5. Digest
    End Sub
End Class
これは、次の方法でテストできます。
Module Module1
    Public Sub Foo(ByVal sender As Object, ByVal e As EventArgs)
        Console.WriteLine("Hmm, freshly baked apple pie.")
    End Sub
    Sub Main()
        Dim pie As New ApplePie()
        AddHandler pie.Baked, AddressOf Foo
        pie.Bake()
        RemoveHandler pie.Baked, AddressOf Foo
    End Sub
End Module
              「!」に関する記事を見つけました。演算子。「辞書検索演算子」とも呼ばれます。以下の記事からの抜粋です。http://panopticoncentral.net/articles/902.aspx
の技術名 operatorは「辞書検索演算子」です。辞書は、英語の辞書のエントリが定義したい単語で索引付けされるのと同じように、番号ではなくキーで索引付けされる任意のコレクション型です。辞書型の最も一般的な例はSystem.Collections.Hashtableです。これにより、(キー、値)のペアをハッシュテーブルに追加し、キーを使用して値を取得できます。たとえば、次のコードは3つのエントリをハッシュテーブルに追加し、キー「Pork」を使用してそのうちの1つを検索します。
Dim Table As Hashtable = New Hashtable
Table("Orange") = "A fruit"
Table("Broccoli") = "A vegetable"
Table("Pork") = "A meat" 
Console.WriteLine(Table("Pork"))
!演算子を使用して、文字列を使用して値にインデックスを付ける任意のディクショナリタイプから値を検索できます。!の後の識別子 ルックアップ操作のキーとして使用されます。したがって、上記のコードは代わりに記述されている可能性があります。
Dim Table As Hashtable = New Hashtable
Table!Orange = "A fruit"
Table!Broccoli = "A vegetable"
Table!Pork = "A meat"
Console.WriteLine(Table!Pork)
2番目の例は1番目の例と完全に同じですが、少なくとも私の目には非常に見栄えがします。たくさんの場所があると思います!特に、XMLとWebの場合、文字列でインデックスが付けられた大量のコレクションがある場合に使用できます。残念な制限の1つは、!それでも有効な識別子である必要があるため、キーとして使用する文字列に無効な識別子文字が含まれている場合は、!オペレーター。(たとえば、「Table!AB $ CD = 5」と言うことはできません。$は識別子では無効だからです。)VB6以前では、括弧を使用して無効な識別子をエスケープすることができました(つまり、「Table![AB $ CD] ")ですが、キーワードをエスケープするために角括弧を使用し始めたとき、それを行う能力を失いました。ほとんどの場合、
本当に技術的にするために、xがストリングまたはオブジェクトをパラメーターとして取るデフォルトのプロパティーを持っている場合、x!yは機能します。その場合、x!yはx.DefaultProperty( "y")に変更されます。興味深いサイドノートは、これをすべて機能させるために言語の字句文法に特別なルールがあるということです。!文字は言語のタイプ文字としても使用され、タイプ文字は演算子の前に使用されます。したがって、特別なルールがなければ、x!yは「x!y」ではなく「x!y」としてスキャンされます。幸いなことに、行内の2つの識別子が有効である場所は言語にはないため、!の後の次の文字が!は識別子の始まりです。演算子であり、タイプ文字ではありません。
これは組み込みであり、C#よりも明らかに有利です。同じ名前を使用せずにインターフェースメソッドを実装する機能。
といった:
Public Sub GetISCSIAdmInfo(ByRef xDoc As System.Xml.XmlDocument) Implements IUnix.GetISCSIInfo
End Sub
              ByValの強制
VBでは、引数を括弧の追加セットで囲む場合、メソッドのByRef宣言をオーバーライドして、それをByValに変換できます。たとえば、次のコードでは、4、5、6ではなく4、5、5が生成されます。
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
プロシージャコールによって変更されない引数-基になる変数を参照してください
名前でパラメーターを渡すため、パラメーターを並べ替える
Sub MyFunc(Optional msg as String= "", Optional displayOrder As integer = 0)
    'Do stuff
End function
使用法:
Module Module1
    Sub Main()
        MyFunc() 'No params specified
    End Sub
End Module
":="パラメータ指定を任意の順序で使用して呼び出すこともできます。
MyFunc(displayOrder:=10, msg:="mystring")
              UsingステートメントはVB 8の新機能で、C#には最初からありました。自動的にdisposeを呼び出します。
例えば
Using lockThis as New MyLocker(objToLock)
End Using
              インポートエイリアスもほとんど不明です。
Import winf = System.Windows.Forms
''Later
Dim x as winf.Form
              次のイベント宣言を検討してください
Public Event SomethingHappened As EventHandler
C#では、次の構文を使用してイベントサブスクライバーを確認できます。
if(SomethingHappened != null)
{
  ...
}
ただし、VB.NETコンパイラはこれをサポートしていません。IntelliSenseに表示されない非表示のプライベートメンバーフィールドを実際に作成します。
If Not SomethingHappenedEvent Is Nothing OrElse SomethingHappenedEvent.GetInvocationList.Length = 0 Then
...
End If
詳しくは:
http://jelle.druyts.net/2003/05/09/BehindTheScenesOfEventsInVBNET.aspx http://blogs.msdn.com/vbteam/archive/2009/09/25/testing-events-for-nothing-null-doug -rothaus.aspx
キーワードの名前と一致する変数名が必要な場合は、角かっこで囲みます。必要ではありません。ただし、ベストプラクティスですが、賢く使用できます。
例えば
Class CodeException
Public [Error] as String
''...
End Class
''later
Dim e as new CodeException
e.Error = "Invalid Syntax"
例:コメント(@Pondidum)の例:
Class Timer
Public Sub Start()
''...
End Sub
Public Sub [Stop]()
''...
End Sub
              XMLリテラルについてはいくつか回答がありますが、この特定のケースについては回答がありません。
XMLリテラルを使用すると、エスケープする必要がある文字列リテラルを囲むことができます。たとえば、二重引用符を含む文字列リテラル。
これの代わりに:
Dim myString = _
    "This string contains ""quotes"" and they're ugly."
あなたはこれを行うことができます:
Dim myString = _
    <string>This string contains "quotes" and they're nice.</string>.Value
これは、CSV解析のリテラルをテストする場合に特に役立ちます。
Dim csvTestYuck = _
    """Smith"", ""Bob"", ""123 Anywhere St"", ""Los Angeles"", ""CA"""
Dim csvTestMuchBetter = _
    <string>"Smith", "Bob", "123 Anywhere St", "Los Angeles", "CA"</string>.Value
(<string>もちろん、タグを使用する必要はありません。好きなタグを使用できます。)
<q>Perl / Rubyでの使用法と同様に、良いタグになります。とにかく、それはかなりいい慣用句です。お気に入り!
                    1行に2行のコードを含めることができます。したがって:
Dim x As New Something : x.CallAMethod
              Call (New Something).CallAMethod()
                    オプションのパラメーター
オプションは、次のような新しいオーバーロードを作成するよりもはるかに簡単です。
Function CloseTheSystem(Optional ByVal msg AS String = "Shutting down the system...")
   Console.Writeline(msg)
   ''//do stuff
End Function
              パラメータを持つプロパティ
私はいくつかのC#プログラミングを行っていて、VB.Netにはなかったがここでは言及されていない機能を発見しました。
これを行う方法の例(およびc#の制限)は、次の場所にあります。パラメーターを指定したC#での一般的なget setプロパティの使用...
私はその答えからコードを抜粋しました:
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