VB.NETの隠された機能?


121

C#の非表示の機能を使用してかなりのブラウジングを学びましたが、VB.NETに似たものを見つけることができなかったときは驚きました。

それで、その隠されたまたはあまり知られていない機能のいくつかは何ですか?

回答:


128

この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

9
特定のSQLExceptionをキャッチしたい場合に便利です。-2と言うと、ネットワークタイムアウトが正しく記憶されます。exをsqlExceptionとしてキャッチex where code。-2
Pondidum

うわー!これを読んですぐに使用し、先週書いたばかりのtry / catchブロックを単純化します。私はこれが存在することを決して新しいことはありません。
ジョンMガント

1
NET CLRチームのブログは説明どこ例外フィルタが有用である理由+1そして、ここだblogs.msdn.com/clrteam/archive/2009/02/05/...
MarkJ

5
これは非表示であるだけでなく、C#でも使用できません。
Cheeso 2009

82

カスタムEnums

VBの本当の隠し機能の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


興味深い-消費したときにこれがどのように見えるかの例を示すことができますか?
ブライアンマッケイ

Ruleコンストラクターを直接呼び出すことで、独自のルールを作成できるように見えますか?もしそうなら、そしてあなたがこれを止めたいのなら、あなたのライブラリーでコンストラクターを "Friend"として宣言できますか?
Joel Coehoorn、2008年

Joel、私のサンプルコードでは、私はこれを禁止していませんでした。むしろ、ユーザーにいくつかの一般的なルールを提供し、独自の特別なルールを作成できるようにします。もちろん、コンストラクタをとしてマークするfriendか、のRule代わりにenum:と同じクラスを使用することで、これを防ぐことができRuleTemplateます。
Konrad Rudolph、

非表示の有用な属性の使用のリストがある場所はありますか?目の前にあるものは信じられないようですが、どこで使用するのか、または列挙型に限定されたジェネリックを持つことができない場合に、主要な不満を解決できるかどうかはまだわかりません。
マズロー

@Maslow:ここに含まれる属性はありません。それはxmlコメントです。
Joel Coehoorn、2009年

49

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*"

3
待って、何?それは私にとって新しいです!うーん、それはVB.NETの文字列操作の代替手段よりもはるかに優れています:D
STW

.. !! 私はいくつかのvb.netプロジェクトで作業しましたが、それを知りませんでした!興味深い機能...
Meta-Knight

woooooooooooooooooooooooow!ありがとう!かっこいい!ELinq、DLinqでも動作しますか?XLinqはどうですか?
Shimmy Weitzhandler 2009

@dotjoeうーん?これらのグロブについて「怠惰」なものは何もありません。
Josh Lee、

これはどのように実行され、内部で何が起こっていますか?それは正規表現ライブラリの同義語ですか?
brumScouse 2010

48

Typedef

VBは、プリミティブな種類のtypedefvia Importエイリアスを知っています。

Imports S = System.String

Dim x As S = "Hello"

これは、ジェネリック型と組み合わせて使用​​するとさらに便利です。

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

2
IDEでImportが認識されない例を示してください。
Shimmy Weitzhandler 2009

5
Importsそのはず。;-)どういうわけか、このエラーはほぼ1年間検出されずに(そして28の賛成投票を獲得して)います。
Konrad Rudolph、

ジェネリックのデフォルトを使用して新しい「タイプ」を作成する方法を常に疑問に思いました!涼しい!
eidylon 2009

3
インポート、インポート、インポート、なんでも!シーッシュ、あなたは私たちそれらを賛成する前にこれらの投稿を読んだと思います!
MarkJ

ビジュアルスタジオテストでxunitを使用するのに最適ですImports Assert = xUnit.Assert
wheelibin

45

ああ!XMLリテラルもお忘れなく。

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

それが私が言おうとしていたことです。実際、意図しない目的でXMLリテラルを使用してきました。私はそれを使用してJavascriptを生成しました... swortham.blogspot.com/2009/03/vb-2008.html
スティーブ

9
特に、XMLリテラルを使用して、醜い文字列のエスケープを回避できます。たとえば、二重引用符を含む文字列を使用している場合などです。:ちょうどこのように、XMLリテラル内の文字列を入れて、値を呼び出して <string>This string contains "quotes" and it's OK.</string>.Value 、すべてのフィールドが引用符にあったCSVファイルを解析する上でテストを書くとき、(私はこれは特に便利見つかったことがない。ない私の手ですべてのそれらの引用符をエスケープする楽しされていますテストライン。)
Ryan Lundy

2
@キラレッサ:+1、素晴らしいコメント。実際、これは複数行の文字列を指定するための優れた方法でもあります(SQLステートメントを抱きしめるなど)。
ハインツィ2009

インラインXMLは、これまで考えられてきた中で最悪のVB.NET機能の1つです。根拠のない事実。
Grant Thomas

39

オブジェクトの初期化もそこにあります!

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

1
中括弧が付いているなんて信じられません。すでにWithステートメントがあります。それらはその構文を再利用できたはずです。
サムアックス

2
私は知っている、それは道に警官がいないことをあなたに示すためだけに作られています...笑JK
シミー・ワイツハンドラー

4
すべてのコンパイラー作成者がそれ自体がC / C ++プログラマーである場合に何が起こるかを考えます。彼らはより良いものを思いつかないので、C構文を他の言語に滑り込ませ続けています。
RBarryYoung 2009

38

DirectCast

DirectCast驚異です。表面上は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()が少し好きです。例外がスローされず、キャストが失敗した場合はNothingが返されます。キャストが頻繁に失敗すると予想される場合は、If TypeOf x Is T ... DirectCast(x、T)よりも速く、DirectCastが失敗した場合に例外をキャッチするよりも確かに高速です。
ボブ・キング

6
DirectCast()とTryCast()は、ペアとして正しく使用すると非常に役立ちます。キャストされるオブジェクトが常にターゲットタイプであると予想される場合は、DirectCast()を使用する必要があります(そうでない場合、エラーが発生します。予期しない状況であるため、問題ありません)。キャストされるオブジェクトが1 つのターゲットタイプまたは複数のターゲットタイプである可能性がある場合は、TryCast()を使用する必要があります。どちらか一方のみを使用すると、余分なオーバーヘッドが発生する(typeof xがyの場合、directcast(x、y)が非効率的である)か、有効なエラーを回避する(オブジェクトが常にターゲットタイプである必要がある場合は、TryCast()を使用する)
STW

Yoooder:100%正解です。TryCast私が主にを使用して選択する骨を持っているので、それは私が当時言及しなかったのは残念ですCType
Konrad Rudolph、

@Maslow:Enumは値型でありTryCast、ドキュメントに従って参照型でのみ機能するため、もちろんそうではありません。
Konrad Rudolph、

+1:へえ。認めざるを得ません。これを読んで、「ああ、DirectCast、どうやってそれを忘れたの?」そして、次のコード行で使用しました(CTypeが本当に嫌いなため)。
RBarryYoung 2009

37

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)

わかりました、私はこれを知りませんでした!私は昨日IIFを使用したばかりなので、そのコードブロックを再確認します。
Sean Gough、

4
VS 2005にそのことを伝えてください。私たち全員が最新かつ最高の仕事をするわけではありません。
サムアーウィン

3
@スラウ、ナンセンス。このメソッドは100%タイプセーフであり、(2番目と3番目の)引数と同じタイプのオブジェクトを返します。さらに、引数間の拡大変換が必要です。そうしないと、型が一致しないためコンパイルエラーが発生します。
Konrad Rudolph、

1
はい、タイプセーフではないIIf()
Pondidum 2009

2
@ Br.Bill実際、これはCおよびPerlの演算子と完全に同等であり:?、単純なバージョンではありません。
Konrad Rudolph、

32

これはいいですね。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

5
実際、あなたはいくつか見落としました:a)複数の変数をテストするための "Select Case True"の使用、b) "Case A、B、..."フォームの使用、そしてc) ":"の適用実行文を条件句で囲みます(多くの人はこれが好きではありません)。
RBarryYoung 2009

6
Select Case Trueは使用しないでください。Ifステートメントを使用するだけです。
ライアンランディ

4
Select Case Trueは、巨大なifelseステートメントよりもはるかに読みやすいと思います。
dwidel 2010

問題は、ステートメントのそれぞれを評価し真であるそれぞれのコードを実行するかのようSelect Case True見えることです。しかし、実際には1つずつ評価され、真の最初のコードのみが実行されます。の構文は、この点ではるかに明確です()。CaseIfIf...Else If...Else If...Else
Ryan Lundy、2011

31

私がいつも使用している主要な時間節約機能の1つはWithキーワードです。

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

必要以上にタイプするのは好きではありません!


しかし、特にWith内にWithがある場合、いくつかの隠れたバグも作成します
Varun Mahajan '19

2
私はあなたが既存のウィズの中に新しいウィズを置くことができることさえ知らなかった。それはずさんなだけです!
ボブ・キング

2ボブ:ずさんではない、と私はお勧めします。これは、注意深く使用するための単なる言語構造です。連続する行に多数のプロパティを設定するのは素晴らしいことですが、複雑なコードの一部でランダムな.Fooを見つけてから、上記のWithステートメントx行を探す必要はありません。
ChrisA

2
C#にこれが欲しいですか?それとも私は眠っていましたか?それはC#のhidden-featuresですでに回答されていますか?;-)
peSHIr 2009年

1
@ブー:あなたは正しいですが、それをウォッチリストに追加できないのは、いらいらです。
メタナイト

31

最高で簡単なCSVパーサー:

Microsoft.VisualBasic.FileIO.TextFieldParser

Microsoft.VisualBasicへの参照を追加することにより、これを他の.Net言語、たとえばC#で使用できます。


5
+1これを考慮せずにC#の人がFileHelpersに実行する方法は奇妙です。FileHelpersは優れていると思いますが、これは外部依存関係です。
MarkJ 2009年

@MarkJ私はそれが無知のせいだと思います
Nathan Koop

私はこのクラスを見つけようとして地獄をググってみましたが、フラグを立ててくれてありがとう!
pingoo


25

メソッドの静的メンバー。

例えば:

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 

また、これは単にクラスの共有メンバーとして宣言するのと同じではありません。この方法で宣言されたアイテムは、スレッドセーフであることが保証されています。このシナリオでは式は決して変わらないので問題ではありませんが、変化する可能性のある他のシナリオもあります。


1
これの1つの用途は、メソッドが呼び出されるたびにインクリメントするカウンターを維持することです。変数が静的とマークされている場合、各メソッド呼び出しで再初期化されません。最初の呼び出しでのみ初期化され、その後はその値を保持します。
ライアンランディ

これが、VB.NETで静的クラスメンバーに「共有」という名前が付けられている理由です
Enrico Campidoglio

Staticは、VB.NETでは従来のVBよりも悪い形式です。静的変数は、可能な限りいつでも、回避する必要があります。
サムアックス

6
@ブー-それはかなり抜本的です。あなたの正当化は何ですか?静的変数は便利だと思います。
MarkJ 2009年

4
上記の例のように使用される静的メソッドは、独自の形式のカプセル化を許可します。メソッドレベルのスコープを持つクラスレベルの変数です。それがなければ、たとえ1つのメソッドでのみ使用している場合でも、クラスメンバーがアクセスできるクラスレベルの変数を作成する必要があります。
ライアンランディ

25

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

1
100万行のコードで針を見つけようとしたとき、私はこれを難しい方法で学びました。通常と整数の除算。良いヒント!
Jason Irwin、

23

私は本当にのように、「私」名前空間のVisual Basic 2005で導入された私の情報と機能のいくつかのグループへのショートカットです。次のタイプの情報にすばやく直感的にアクセスできます。

  • My.Computer:ファイルシステム、ネットワーク、デバイス、システム情報など、コンピューターに関連する情報へのアクセス。My.Computer.Network、My.Computer.FileSystem、Myなど、非常に重要なリソースへのアクセスを提供します。 .Computer.Printers。
  • My.Application:名前、バージョン、現在のディレクトリなど、特定のアプリケーションに関連する情報へのアクセス。
  • My.User:現在認証されているユーザーに関連する情報へのアクセス。
  • My.Resources:厳密に型指定された方法でリソースファイルにあるアプリケーションが使用するリソースへのアクセス。
  • My.Settings:厳密に型指定された方法でアプリケーションの構成設定にアクセスします。

これはすばらしいことであり、vb.netのすべての人はMy名前空間の情報を知っている必要があります。とても便利です。
dr。邪悪な

My。* FTW :)。
dr。邪悪な

3
ちょっと便利なのですが、私は馬鹿げた名前が嫌いです。このsecretgeek.net/refactvb.aspを
MarkJ 09/09/06

23

カスタムイベント

あまり役に立ちませんが、イベント処理は大幅にカスタマイズできます。

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

かっこいいようですが、これが必要な場合は、何か間違ったことをしたと思います;-)。KISSの原則に反しているように見えます。
chrissie1 2008

4
1つ以上が例外をスローした場合でも、すべてのシンクが確実にイベントを取得するようにしたい場合に、これは本当に便利です。
ジョナサンアレン

別の値(MSDNサイトで読んだところです)は、クラスが多くのイベントをスローする場合、各イベントのフィールドを宣言するのではなく、コンテナーとしてハッシュテーブル/辞書を使用するように強制できます。 msdn.microsoft.com/en-us/library/8627sbea(VS.71).aspx
チュートリアル

涼しい。これは、C#とVB.NETを区別する機能の1つだと思いました(1つは可能ですが、もう1つは構文がありません)。少なくとも私がこの点で間違っていたことを知ってよかった。
peSHIr 2009年

21

「!」に関する記事を見つけました。演算子。「辞書検索演算子」とも呼ばれます。以下の記事からの抜粋です。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つの識別子が有効である場所は言語にはないため、!の後の次の文字が!は識別子の始まりです。演算子であり、タイプ文字ではありません。


11
これは、私が意図的に忘れていた機能の1つです。それはいくつかのキーストロークを節約しますが、私のコードの強調表示と読みやすさを混乱させます。 もう一度忘れる.... NOW
STW

3
興味深いが、実際には役に立たない。これは、yieldキーワードのような不足している機能を追加する代わりに、VBチームが取り組んでいる種類のことですか?:P
メタナイト

5
この機能は、VB3(私の知る限り)から下位互換性のために行われる
エドゥアルドMolteni

1
キー付きインデックスを実装するクラスには、継承元の共通インターフェースがありますか?整数のインデックス付きコンテナーがIENumberableを実装するのと同じようにIKeyedのように?
マズロー

2
この機能は、LINQ to DataSetsで非常に便利なDataRows(つまりdr!ID)でも機能します。
ポール、

19

これは組み込みであり、C#よりも明らかに有利です。同じ名前を使用せずにインターフェースメソッドを実装する機能。

といった:

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

End Sub

私はあなたがC#でこのようなことをできることを確信しています。VB.NETではそれが強制され、C#ではオプションですか?
Jesper Blad Jensen

5
また、サブプライベートを作成することもできます。これは、非推奨のバージョンのインターフェースの呼び出しなどを非表示にする優れた方法です。
Craig Gidney、

3
それは良い考えです。古典的な例は、IDisposableのDispose実装としても機能するPublic Closeメソッドが必要な場合です。
MarkJ 2009年

1
これは、メソッド名を共有する2つのインターフェースを実装する場合にも非常に役立ちます。
エリックニコルソン'05年

私はこれを見てきましたが、いつも見ていなかったらいいのにと思っています。許可されるべきではありません。
FastAl

17

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

プロシージャコールによって変更されない引数-基になる変数を参照してください


6
ああ私の良さ...それは注目すべき機能ですが、他の人のコードで読んだ場合、それが何をしていたのかはわかりません。何をしているのかを知るためだけにコメントする必要がある場合は、代わりにスローアウェイ変数を渡してください。
mattmc3 2010

7
これは実際には括弧の使用の副作用です-括弧は、たとえ1つのアイテムであっても、内部にあるものの一時的な値を作成します。この効果はvb6で私を殺しました-Sub呼び出しは括弧を取りませんでしたが、Cから来た私は本能的に括弧を入れました。 「byref」。約3年おきに、最後の事件を忘れるのにかかった時間。
FastAl

16

名前でパラメーターを渡すため、パラメーターを並べ替える

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")

わあ、これはすごいかっこいい!Webサービスなどを使用しているときにこれを確認しましたが、通常の方法でこれを実行できることを知りませんでした。
RichC 2008

2
引数が多すぎるメソッドに遭遇した場合、間違いなく非常に便利なツールです。各パラメーターに名前を付けて、name:= valueを1行に記述します。5(私の経験則)を超えるパラメーターを取るメソッドの方が、はるかに直感的でクリーンです。
STW

何十ものオプションの引数を持つメソッドに対処する必要があるOfficeオートメーションに特に役立ちます。
MarkJ 2009年

1
また、2つを組み合わせることができるというのもすばらしい点です。最初に必要なパラメーターを順番に指定し、次にオプションの引数を名前付きパラメーターに切り替えます。
RBarryYoung

15

UsingステートメントはVB 8の新機能で、C#には最初からありました。自動的にdisposeを呼び出します。

例えば

Using lockThis as New MyLocker(objToLock)

End Using

23
1つのUsingステートメントで複数のDisposableオブジェクトをラップできることに注意してください(少なくとも2回忘れてしまったためです)。構文は「objAを新しいオブジェクトとして使用し、objBを新しいオブジェクトとして使用する...」です。これは、複数のUsingステートメントをネストするよりもずっとクリーンです。
STW

間違いなく私のお気に入りの1つでもあります。
サムアックス

14

インポートエイリアスもほとんど不明です。

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form

1
私たちは同じ考えを持っていたと思います。
chrissie1 2008

3
@Boo-インポートエイリアスが悪ではない簡単な例を次に示します。 stackoverflow.com/questions/92869/...
torial

わかりました-不正行為には明らかな手段がありますが、@ torialの怒りに関係なく、これは優れた機能です。System.Text.RegularExpressionsを含めるたびに、 "Group"クラスと名前が競合する危険があります。これは、これが一般的なクラス名だからです。エイリアスを使用すると、あいまいなクラスを完全に修飾する必要がなくなり、時間を大幅に節約でき、適切に使用すると読みやすさが向上します。機能は素晴らしいですが、あなたの特定の例はある種の嘲笑を招いています-申し訳ありません。
mattmc3 2010

14

次のイベント宣言を検討してください

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


どうしてそんなことしたいの?VBでイベントのサブスクライバーの数を知る必要があるユースケースは想像できません。
Konrad Rudolph

特定の状況では、イベントを発生させ、ハンドラーがない場合、C#は例外をスローします。VB.Netはしません。したがって、チェックする必要があります。
Joel Coehoorn、2008

2
これを、サブスクライバーに検証エラーメッセージを生成するビジネスオブジェクトイベントに使用しました。イベントが処理されているかどうかを確認して、検証エラーが受信されていることを確認したいと思いました。それ以外の場合は、ビジネスオブジェクトに例外をスローさせました。
テクノバブル

2
このプライベートメンバーのもう1つの便利な使い方は、イベントの呼び出しリストを取得することです。これをいくつかのケースで使用して、すべての呼び出し元に非同期でイベントを発生させました(リスナーBがイベントを受け取る前にリスナーAがイベントを変更できないようにします。また、リスナーAがリスナーBへの配信を遅延させないようにします)。これをカスタムデータ同期シナリオやAPIでよく使用しました。
STW

14

キーワードの名前と一致する変数名が必要な場合は、角かっこで囲みます。必要ではありません。ただし、ベストプラクティスですが、賢く使用できます。

例えば

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

この例は、キーワード例として「If」を使用しなかった場合に適していると思います。
Sean Gough、

4
timer.Startとtimer.Stopの良い使い方の例として、春を思い出してください
ポンディダム

5
免責事項でそれを指摘するための+1。正しく解決するためにこれを必要とするいくつかのフレームワーククラスがあります。たとえば、[アセンブリ]
STW

5
[列挙型]は、キーワードの代わりにクラスを使用するためにブラケットが必要な場合のもう1つの良い例です。
ライアンランディ

13

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>もちろん、タグを使用する必要はありません。好きなタグを使用できます。)


3
<q>Perl / Rubyでの使用法と同様に、良いタグになります。とにかく、それはかなりいい慣用句です。お気に入り!
コンラートルドルフ

なんて天才的なアイデアだ。ありがとう
ジェレミー

12

DateTimeは、日付を#で囲むことで初期化できます。

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

この構文とともに型推論を使用することもできます

Dim independanceDay = #7/4/1776#

コンストラクタを使用するよりもはるかに優れています

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

6
Option Strict Onの場合は不可
danlash

12

1行に2行のコードを含めることができます。したがって:

Dim x As New Something : x.CallAMethod

whoa ...これはクラスと継承でのみ可能だと思いました
Jason

忘れないでくださいCall (New Something).CallAMethod()
ジョナサンアレン

これは、アップルのMS-Basicのホールダーです] [!私の店では、Gotosを使用するのと同じようにばかげています:-/
FastAl

ほとんどの場合、これは回避する必要がありますが、私が使用したいのは、行が本当に短い場合のステートメントです。例:Case 4:x = 22
dwidel

11

オプションのパラメーター

オプションは、次のような新しいオーバーロードを作成するよりもはるかに簡単です。

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

1
C#がそれらを取得することに気づいていませんでした。それらはすばらしいですが、コードがC#でサポートされていないため、C#によってコードが消費されないことが確実な場合にのみ使用するように注意する必要があります。FxCop / Code Analysisは代わりにメソッドをオーバーロードするよう指示します。
STW

...プロダクションコードに含めないようにしながら、オプションパラメーターの優れた使用法を見つけました。私は自分のサイトにそれについて短い投稿を書きました:yoooder.com/wordpress/?p
STW

2
ああ、私はこれをあまり
嫌っ

9

VB.Netのタイトルケースは、古いVB6 fxnで実現できます。

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

1
また、textinfoクラスにもあります。どの名前空間にあるかは不明です。おそらくsystem.text
Shawn

.net言語に中立で、グローバリゼーションTextInfoクラスを使用してToTitleCaseを変換する方がよいでしょう。コードをC#に変換する必要がある場合、Microsoft.VisualBasicを必要とする多くの小さな問題が発生します
Jeremy

9

パラメータを持つプロパティ

私はいくつかの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

これはおもしろいですが、これがどこで役に立つかは完全にはわかりません。myObj.Something( "abc")は、プロパティよりも関数にアクセスしているように見えます。これで何が買えるのかわかりません。
mattmc3 2010

あいまいさは嫌いです。それはどうあるべきか。メソッド、またはプロパティ。一部のリファクタリングツールは、特定の状況でも両方を作成することを提案し、それらも知らないように見えます...
brumScouse 2010
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.