web-dev-qa-db-ja.com

VB.NETの非表示機能

C#の非表示機能 を参照してかなり多くのことを学びましたが、VB.NETに似たものが見つからなかったときは驚きました。

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

121
Sean Gough

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
128
torial

カスタムEnums

VB=)の実際のhidden機能の1つは、使用できるcompletionlist XMLドキュメントタグです。拡張機能を備えた独自のEnumのような型を作成するには、この機能は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はRuleTemplatesからの可能な値のIntelliSenseリストを提供します。

/編集:

これはIDEに依存する機能であるため、これを使用したときの外観を示すのは困難ですが、スクリーンショットを使用します。

アクションの完了リストhttp://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png

実際、IntelliSenseはEnumを使用した場合に得られるものと100%同じです。

82
Konrad Rudolph

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

Typedefs

VBは、typedefエイリアスを介してImportの原始的な種類を知っています。

Imports S = System.String

Dim x As S = "Hello"

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

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

ああ! XML Literals を忘れないでください。

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

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

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

DirectCast

DirectCastは素晴らしいです。表面的には、オブジェクトをあるタイプから別のタイプに変換するという点で、CType演算子と同様に機能します。ただし、より厳密な一連のルールで機能します。したがって、CTypeの実際の動作は多くの場合不透明であり、どの種類の変換が実行されるかはまったく明らかではありません。

DirectCastは、2つの異なる操作のみをサポートします。

  • 値型のボックス化解除、および
  • クラス階層でのアップキャスト。

他のキャストは機能せず(たとえば、IntegerDoubleにアンボックスしようとすると)、コンパイル時/実行時エラーが発生します(状況と静的型によって検出できるものによって異なります)確認)。したがって、可能な限りDirectCastを使用します。これは私の意図を最もよく捉えているためです。状況に応じて、既知のタイプの値をボックス解除するか、アップキャストを実行します。話の終わり。

一方、CTypeを使用すると、コードの読者は、ユーザー定義コードの呼び出しを含むあらゆる種類の異なる操作を解決するため、プログラマーが実際に何を意図していたのか疑問に思うでしょう。

なぜこれが隠された機能ですか? VBチームはガイドラインを公開しました1 コードをより均一にするためにDirectCastを使用しないようにします(実際には高速ですが!)。私は、これは逆にするべき悪いガイドラインであると主張します:可能な限り、より一般的なDirectCast演算子よりもCTypeを優先します。それはコードをより明確にします。一方、CTypeは、これが実際に意図されている場合、つまり、縮小するCType演算子(cf. operator overloading )を呼び出す必要がある場合にのみ呼び出す必要があります。


1) 私はガイドラインへのリンクを思い付くことができませんが、私は見つけました Paul Vickのそれについての (VBチーム)の最高の開発者:

現実の世界では、違いに気付くことはほとんどないため、CType、CIntなどのより柔軟な変換演算子を使用することもできます。


(Zackによる編集:詳細はこちら: VB.NETでのキャスト方法

38
Konrad Rudolph

If条件付き合体演算子

どのように非表示にするかわかりませんが、Iif([expression]、[trueの場合value]、[falseの場合value])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)
_
37
Konrad Rudolph

これはいいものです。 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
32
torial

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

Microsoft.VisualBasic.FileIO.TextFieldParser

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

31
cjk

私がいつも使っている大きな時間節約の1つは、Withキーワードです。

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

必要以上に入力するのは好きではありません!

31
Jasha87
  • AndAlso/OrElse論理演算子

(編集:詳細はこちら: AndAlso演算子とOrElse演算子を常に使用する必要がありますか?

26
Joel Coehoorn

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
25
Shimmy

メソッドの静的メンバー

例えば:

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 

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

25
Joel Coehoorn

Visual Basic 2005で導入された"My"名前空間が本当に好きです。Myは、いくつかの情報グループへのショートカットですおよび機能。次の種類の情報にすばやく直感的にアクセスできます。

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

カスタムイベント

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

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
23
Konrad Rudolph

「!」に関する記事を見つけました。 「辞書検索演算子」とも呼ばれる演算子。以下の記事からの抜粋です: http://panopticoncentral.net/articles/902.aspx

!の技術名operatorは「辞書検索演算子」です。辞書は、英語の辞書のエントリが定義するWordによってインデックス付けされる方法と同様に、数字ではなくキーによってインデックス付けされる任意のコレクションタイプです。辞書タイプの最も一般的な例はSystem.Collections.Hashtableです。これにより、(キー、値)のペアをハッシュテーブルに追加し、キーを使用して値を取得できます。たとえば、次のコードはハッシュテーブルに3つのエントリを追加し、キー「ポーク」を使用してそのうちの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つの識別子が有効な場所がないため、!の後の次の文字がは識別子の始まりで、!型文字ではなく演算子になります。

21
torial

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

といった:

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

End Sub
19
torial

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

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

17
Chris Haas

パラメータを名前で渡し、並べ替えます

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

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

例えば。

Using lockThis as New MyLocker(objToLock)

End Using
15
torial

キーワードの変数名と一致する変数名が必要な場合は、括弧で囲みます。必要ないしかし、ベストプラクティス-しかし、それは賢明に使用することができます。

例えば.

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
14
torial

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

Import winf = System.Windows.Forms

''Later
Dim x as winf.Form
14
torial

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

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.aspxhttp://blogs.msdn.com/vbteam/archive/2009/09/25/ testing-events-for-nothing-null-doug-rothaus.aspx

14
Technobabble

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

13
Ryan Lundy

1行で2行のコードを使用できます。したがって:

Dim x As New Something : x.CallAMethod
12
Parsa

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

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

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

Dim independanceDay = #7/4/1776#

それは、コンストラクタを使用するよりもずっといいです

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

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

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

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

ステートメントを一緒に使用して複数のスタック/グループ:

Dim sql As String = "StoredProcedureName"
Using cn As SqlConnection = getOpenConnection(), _
      cmd As New SqlCommand(sql, cn), _
      rdr As SqlDataReader = cmd.ExecuteReader()

    While rdr.Read()

        ''// Do Something

    End While

End Using

公平を期すために、C#でも実行できます。しかし、多くの人はどちらの言語でもこれについて知りません。

9
Joel Coehoorn

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

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

パラメータ付きのプロパティ

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

多くのバグを解決するのに非常に役立ち、助けとなった機能の1つは、特にオプションを使用する場合に、関数に引数を明示的に渡すことです。

以下に例を示します。

Public Function DoSomething(byval x as integer, optional y as boolean=True, optional z as boolean=False)
' ......
End Function

次のように呼び出すことができます:

DoSomething(x:=1, y:=false)
DoSomething(x:=2, z:=true)
or
DoSomething(x:=3,y:=false,z:=true)

これは非常にきれいでバグがなく、このような関数を呼び出します

DoSomething(1,true)
8
Youssef

Whenを使用した洗練されたエラー処理

Catch ex As IO.FileLoadException When attempt < 3行でwhenが使用されていることに注意してください。

Do
  Dim attempt As Integer
  Try
    ''// something that might cause an error.
  Catch ex As IO.FileLoadException When attempt < 3
    If MsgBox("do again?", MsgBoxStyle.YesNo) = MsgBoxResult.No Then
      Exit Do
    End If
  Catch ex As Exception
    ''// if any other error type occurs or the attempts are too many
    MsgBox(ex.Message)
    Exit Do
  End Try
  ''// increment the attempt counter.
  attempt += 1
Loop

最近閲覧した VbRad

7
Eduardo Molteni

次のことを知らなかった場合、本当にそうだとは思わないでしょう。これは、C#に大きな時間がないことです。

(XMLリテラルと呼ばれます)

Imports <xmlns:xs="System">

Module Module1

  Sub Main()
    Dim xml =
      <root>
        <customer id="345">
          <name>John</name>
          <age>17</age>
        </customer>
        <customer id="365">
          <name>Doe</name>
          <age>99</age>
        </customer>
      </root>

    Dim id = 1
    Dim name = "Beth"
    DoIt(
      <param>
        <customer>
          <id><%= id %></id>
          <name><%= name %></name>
        </customer>
      </param>
    )

    Dim names = xml...<name>
    For Each n In names
      Console.WriteLine(n.Value)
    Next

    For Each customer In xml.<customer>
      Console.WriteLine("{0}: {1}", customer.@id, customer.<age>.Value)
    Next

    Console.Read()
  End Sub

  Private Sub CreateClass()
    Dim CustomerSchema =
      XDocument.Load(CurDir() & "\customer.xsd")

    Dim fields =
      From field In CustomerSchema...<xs:element>
      Where field.@type IsNot Nothing
      Select
        Name = field.@name,
        Type = field.@type

    Dim customer = 
      <customer> Public Class Customer 
<%= From field In fields Select <f> 
Private m_<%= field.Name %> As <%= GetVBPropType(field.Type) %></f>.Value %>

                     <%= From field In fields Select <p> 
Public Property <%= field.Name %> As <%= GetVBPropType(field.Type) %>
 Get 
Return m_<%= field.Name %> 
End Get
 Set(ByVal value As <%= GetVBPropType(field.Type) %>)
 m_<%= field.Name %> = value 
End Set
 End Property</p>.Value %> 
End Class</customer>

    My.Computer.FileSystem.WriteAllText("Customer.vb",
                                        customer.Value,
                                        False,
                                        System.Text.Encoding.ASCII)

  End Sub

  Private Function GetVBPropType(ByVal xmlType As String) As String
    Select Case xmlType
      Case "xs:string"
        Return "String"
      Case "xs:int"
        Return "Integer"
      Case "xs:decimal"
        Return "Decimal"
      Case "xs:boolean"
        Return "Boolean"
      Case "xs:dateTime", "xs:date"
        Return "Date"
      Case Else
        Return "'TODO: Define Type"
    End Select
  End Function

  Private Sub DoIt(ByVal param As XElement)
    Dim customers =
      From customer In param...<customer>
      Select New Customer With
      {
        .ID = customer.<id>.Value,
        .FirstName = customer.<name>.Value
      }

    For Each c In customers
      Console.WriteLine(c.ToString())
    Next
  End Sub

  Private Class Customer
    Public ID As Integer
    Public FirstName As String
    Public Overrides Function ToString() As String
      Return <string>
ID : <%= Me.ID %>
Name : <%= Me.FirstName %>
             </string>.Value
    End Function

  End Class
End Module
'Results:

ID : 1
Name : Beth
John
Doe
345: 17
365: 99

XML Literals Tips/Tricks Beth Massiをご覧ください。

7
Shimmy

1行にIfを含めることができます。

If True Then DoSomething()
7
Parsa
  • 親をインポートした後、子の名前空間はスコープ内にあります。たとえば、System.IOをインポートしたり、Fileクラスを使用するためにSystem.IO.Fileを言う必要はなく、IO.Fileと言うだけで済みます。これは簡単な例です。機能が本当に役立つ場所がありますが、C#はそれを行いません。
7
Joel Coehoorn

これは私が見たことのない面白いものです。私はそれがVS 2008で動作することを知っています、少なくとも:

誤ってVBセミコロンを含む行を終了した場合、C#を実行しすぎているため、セミコロンは自動的に削除されます。実際に(少なくともVS 2008では)少なくともVB行をセミコロンで終了することはできません。試してください!

(完全ではありません。最終クラス名の途中でセミコロンを入力すると、クラス名はオートコンプリートされません。)

6
Ryan Lundy

VB=)のC言語のbreakとは異なり、ExitまたはContinueを使用してブロックを作成できます。

For i As Integer = 0 To 100
    While True
        Exit While
        Select Case i
            Case 1
                Exit Select
            Case 2
                Exit For
            Case 3
                Exit While
            Case Else
                Exit Sub
        End Select
        Continue For
    End While
Next
6
Parsa
IIf(False, MsgBox("msg1"), MsgBox("msg2"))

結果は何ですか? 2つのメッセージボックス!!!!これは、関数に到達するとIIf関数が両方のパラメーターを評価するために発生します。

VBには新しいIf演算子があります(C#?:演算子と同様):

If(False, MsgBox("msg1"), MsgBox("msg2"))

2番目のmsgboxのみを表示します。

一般的に、両方の項目を評価する必要がない限り、vbコードのすべてのIIFを置き換えることをお勧めします。

Dim value = IIf(somthing, LoadAndGetValue1(), LoadAndGetValue2())

両方の値がロードされたことを確認できます。

5
Shimmy

名前を[と]で囲むと、プロパティと変数名に予約キーワードを使用できます

Public Class Item
    Private Value As Integer
    Public Sub New(ByVal value As Integer)
        Me.Value = value
    End Sub

    Public ReadOnly Property [String]() As String
        Get
            Return Value
        End Get
    End Property

    Public ReadOnly Property [Integer]() As Integer
        Get
            Return Value
        End Get
    End Property

    Public ReadOnly Property [Boolean]() As Boolean
        Get
            Return Value
        End Get
    End Property
End Class

'Real examples:
Public Class PropertyException : Inherits Exception
    Public Sub New(ByVal [property] As String)
        Me.Property = [property]
    End Sub

    Private m_Property As String
    Public Property [Property]() As String
        Get
            Return m_Property
        End Get
        Set(ByVal value As String)
            m_Property = value
        End Set
    End Property
End Class

Public Enum LoginLevel
    [Public] = 0
    Account = 1
    Admin = 2
    [Default] = Account
End Enum
5
Shimmy

Parsa's answerと同様に、 like operator にはlotsが一致するものがあり、上記の単純なワイルドカード。 MSDN docoを読んで、椅子から落ちそうになりました:-)

5
Dan F

VB8および以前のバージョンでは、導入する変数に型を指定しなかった場合、オブジェクト型は自動的に検出されました。 VB9(2008)では、Option InferがOn(デフォルト)に設定されている場合、DimはC#のvarキーワードのように動作します。

5
Parsa

複数のIf/ElseIf/Elseステートメントの代わりにCaseを選択します。

この例では、単純なジオメトリオブジェクトを想定しています。

Function GetToString(obj as SimpleGeomertyClass) as String
  Select Case True
    Case TypeOf obj is PointClass
      Return String.Format("Point: Position = {0}", _
                            DirectCast(obj,Point).ToString)
    Case TypeOf obj is LineClass
      Dim Line = DirectCast(obj,LineClass)
      Return String.Format("Line: StartPosition = {0}, EndPosition = {1}", _
                            Line.StartPoint.ToString,Line.EndPoint.ToString)
    Case TypeOf obj is CircleClass
      Dim Line = DirectCast(obj,CircleClass)
      Return String.Format("Circle: CenterPosition = {0}, Radius = {1}", _
                            Circle.CenterPoint.ToString,Circle.Radius)
    Case Else
      Return String.Format("Unhandled Type {0}",TypeName(obj))
  End Select
End Function
5
Clif

Vb.netで配列を宣言するときは、常に「0〜xx」構文を使用します。

Dim b(0 to 9) as byte 'Declares an array of 10 bytes

これにより、配列のスパンが非常に明確になります。同等のものと比較してください

Dim b(9) as byte 'Declares another array of 10 bytes

2番目の例が10個の要素で構成されていることを知っていても、それは明らかではありません。そして、私は上記を望んでいる代わりに書いたプログラマーからコードを見た回数を思い出すことができません

Dim b(10) as byte 'Declares another array of 10 bytes

もちろんこれは完全に間違っています。 As b(10)は11バイトの配列を作成します。何を探すべきかわからない人にとっては正しいように見えるため、バグを簡単に引き起こす可能性があります。

「0からxx」の構文は、以下でも動作します

Dim b As Byte() = New Byte(0 To 9) {} 'Another way to create a 10 byte array
ReDim b(0 to 9) 'Assigns a new 10 byte array to b

完全な構文を使用することで、将来コードを読む人に、自分が何をしていたかを知っていることを示すこともできます。

5
Marcus Andrén

C#とは異なり、VBでは、null不可アイテムのデフォルト値を使用できます。

Sub Main()
    'Auto assigned to def value'
    Dim i As Integer '0'
    Dim dt As DateTime '#12:00:00 AM#'
    Dim a As Date '#12:00:00 AM#'
    Dim b As Boolean 'False'

    Dim s = i.ToString 'valid
End Sub

一方、C#では、これはコンパイラエラーになります。

int x;
var y = x.ToString(); //Use of unassigned value
4
Shimmy

VB.NETプロジェクトは、デフォルトで、プロジェクトのプロパティの一部であるルート名前空間を持っていることを覚えておくことも重要です。デフォルトでは、このルート名前空間はプロジェクトと同じ名前になります。 Namespaceブロック構造を使用する場合、名前は実際にそのルート名前空間に追加されます。たとえば、プロジェクトの名前がMyProjectの場合、変数を次のように宣言できます。

Private obj As MyProject.MyNamespace.MyClass

ルート名前空間を変更するには、[プロジェクト]-> [プロパティ]メニューオプションを使用します。ルート名前空間も同様にクリアできます。つまり、すべてのNamespaceブロックが含まれるコードのルートレベルになります。

4
Nescio

MyClassキーワードは、派生クラスのオーバーライドを無視して、元の実装としてクラスインスタンスメンバーを参照する方法を提供します。

4
Parsa

Nothingキーワードは、コンテキストに応じてdefault(T)またはnullを意味する場合があります。これを活用して、非常に興味深い方法を作成できます。

'''<summary>Returns true for reference types, false for struct types.</summary>'
Public Function IsReferenceType(Of T)() As Boolean
    Return DirectCast(Nothing, T) Is Nothing
End Function
4
Craig Gidney

名前空間のエイリアス

Imports Lan = Langauge

VB.Netに固有のものではありませんが、名前空間の競合が発生すると忘れられることがよくあります。

3
chrissie1

VBはOnErrorステートメントも提供します。しかし、最近ではあまり役に立たない。

On Error Resume Next
' Or'
On Error GoTo someline
</ code>
3
Parsa

「=」の代わりにREMを使用して行をコメントアウトできます。

2
Booji Boy

Nullable Dates!これは、データベース(この場合はMSSQL Server)に出入りするデータがある場合に特に役立ちます。値が設定されたSmallDateTimeパラメーターを提供する2つの手順があります。そのうちの1つは、単純に古い日付を取り、その中に値があるかどうかをテストして、デフォルトの日付を割り当てます。もう1つのバージョンはNullable(Of Date)を受け入れるので、日付を値なしのままにしておくことができ、ストアドプロシージャからのデフォルトは何でも受け入れます。

<System.Diagnostics.DebuggerStepThrough> _
Protected Function GP(ByVal strName As String, ByVal dtValue As Date) As SqlParameter
    Dim aParm As SqlParameter = New SqlParameter
    Dim unDate As Date
    With aParm
        .ParameterName = strName
        .Direction = ParameterDirection.Input
        .SqlDbType = SqlDbType.SmallDateTime
        If unDate = dtValue Then    'Unassigned variable
            .Value = "1/1/1900 12:00:00 AM" 'give it a default which is accepted by smalldatetime
        Else
            .Value = CDate(dtValue.ToShortDateString)
        End If
    End With
    Return aParm
End Function
<System.Diagnostics.DebuggerStepThrough()> _
Protected Function GP(ByVal strName As String, ByVal dtValue As Nullable(Of Date)) As SqlParameter
    Dim aParm As SqlParameter = New SqlParameter
    Dim unDate As Date
    With aParm
        .ParameterName = strName
        .Direction = ParameterDirection.Input
        .SqlDbType = SqlDbType.SmallDateTime
        If dtValue.HasValue = False Then
            '// it's nullable, so has no value
        ElseIf unDate = dtValue.Value Then    'Unassigned variable
            '// still, it's nullable for a reason, folks!
        Else
            .Value = CDate(dtValue.Value.ToShortDateString)
        End If
    End With
    Return aParm
End Function
2
Private Sub Button1_Click(ByVal sender As Button, ByVal e As System.EventArgs)
        Handles Button1.Click
    sender.Enabled = True
    DisableButton(sender)
End Sub

Private Sub Disable(button As Object)
    button.Enabled = false
End Sub

このスニペットには、C#ではできない2つの(おそらくそれ以上の)ことがあります。

  1. Button1.Clickを処理-ハンドラーを外部からイベントにアタッチします!
  2. VBの暗黙性により、ハンドラーの最初のパラメーターを拡張タイプとして宣言できます。 C#では、期待される型であっても、別のパターンにデリゲートをアドレスすることはできません。

また、C#ではオブジェクトに期待される機能を使用できません-C#ではそれを夢見ることができます(今では動的キーワードを作成しましたが、VBからはかけ離れています)。 C#では、(new object())。Enabledと記述すると、タイプオブジェクトにメソッド 'Enabled'がないというエラーが表示されます。今、私はこれが安全かどうかをお勧めする人ではありません、情報は現状のままで提供され、自分でバスを動かしますが、時には(COMオブジェクトで作業するときなど)これはとても良いことです。個人的には、期待される値が確実にボタンである場合は常に(ボタンとして送信)を記述します。

さらに、次の例をご覧ください。

Private Sub control_Click(ByVal sender As Control, ByVal e As System.EventArgs)
        Handles TextBox1.Click, CheckBox1.Click, Button1.Click
    sender.Text = "Got it?..."
End Sub
2
Shimmy

VBでインターフェイスメンバを明示的に実装することはできませんが、別の名前で実装することは可能です。

Interface I1
    Sub Foo()
    Sub TheFoo()
End Interface

Interface I2
    Sub Foo()
    Sub TheFoo()
End Interface

Class C
    Implements I1, I2

    Public Sub IAmFoo1() Implements I1.Foo
        ' Something happens here'
    End Sub

    Public Sub IAmFoo2() Implements I2.Foo
        ' Another thing happens here'
    End Sub

    Public Sub TheF() Implements I1.TheFoo, I2.TheFoo
        ' You shouldn't yell!'
    End Sub
End Class

Microsoft Connect でこの機能に投票してください。

2
Parsa

あなたがそれをどのように非表示にするかわかりませんが、 If 演算子はカウントできます。

ある意味では、多くのCライクな言語の?:(三項)または??演算子に非常に似ています。ただし、すべてのパラメーターを評価することに注意することが重要です。そのため、例外が発生する可能性のあるもの(意図しない場合)または意図しない副作用を引き起こす可能性のあるものを渡さないことが重要です。

使用法:

Dim result = If(condition, valueWhenTrue, valueWhenFalse)
Dim value = If(obj, valueWhenObjNull)
2
Sam Erwin

以前はオプションの関数パラメーターが非常に好きでしたが、C#とVBを何度もやり直す必要があります。C#はいつサポートしますか? Cには(ある種の)それらがありました!

1
Joel Coehoorn

ByValByRefキーワードの違い:

Module Module1

    Sub Main()
        Dim str1 = "initial"
        Dim str2 = "initial"
        DoByVal(str1)
        DoByRef(str2)

        Console.WriteLine(str1)
        Console.WriteLine(str2)
    End Sub

    Sub DoByVal(ByVal str As String)
        str = "value 1"
    End Sub

    Sub DoByRef(ByRef str As String)
        str = "value 2"
    End Sub
End Module

'Results:
'initial
'value 2
1
Shimmy

コードの文書化

''' <summary>
''' 
''' </summary>
''' <remarks></remarks>
Sub use_3Apostrophe()
End Sub
1
PdotWang

いつかBasicユーザーは変数を導入しませんでした。彼らはそれらを使用するだけでそれらを紹介しました。 VBのOption Explicitは、不適切な入力によって誤って変数を導入しないようにするために導入されました。いつでもオフにして、Basicで作業した日々を体験できます。

1
Parsa

再びオプションの引数!

Function DoSmtg(Optional a As string, b As Integer, c As String)
    'DoSmtg
End 

' Call
DoSmtg(,,"c argument")

DoSmtg(,"b argument")
0
Hedi Guizani

メソッドの属性!たとえば、設計時に使用できないプロパティは、1)プロパティウィンドウから非表示、2)シリアル化されない(特にユーザーコントロール、またはデータベースからロードされるコントロールにとって面倒です):

_<System.ComponentModel.Browsable(False), _
System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden), _
System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always), _
System.ComponentModel.Category("Data")> _
Public Property AUX_ID() As String
    <System.Diagnostics.DebuggerStepThrough()> _
     Get
        Return mAUX_ID
    End Get
    <System.Diagnostics.DebuggerStepThrough()> _
     Set(ByVal value As String)
        mAUX_ID = value
    End Set
End Property
_

DebuggerStepThrough()を入れることも非常に役立つある程度のデバッグを行う場合(関数内などにブレークポイントを置くことができますが、 tその機能をシングルステップで実行します)。

また、物事をカテゴリに分類する機能(「データ」など)は、doプロパティツールにプロパティを表示する場合-window、その特定のプロパティはそのカテゴリに表示されます。

0
Sub Main()
    Select Case "value to check"
        'Check for multiple items at once:'
        Case "a", "b", "asdf" 
            Console.WriteLine("Nope...")
        Case "value to check"
            Console.WriteLine("Oh yeah! thass what im talkin about!")
        Case Else
            Console.WriteLine("Nah :'(")
    End Select


    Dim jonny = False
    Dim charlie = True
    Dim values = New String() {"asdff", "asdfasdf"}
    Select Case "asdfasdf"
        'You can perform boolean checks that has nothing to do with your var.,
        'not that I would recommend that, but it exists.'
        Case values.Contains("ddddddddddddddddddddddd")
        Case True
        Case "No sense"
        Case Else
    End Select

    Dim x = 56
    Select Case x
        Case Is > 56
        Case Is <= 5
        Case Is <> 45
        Case Else
    End Select

End Sub
0
Shimmy