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
Enum
sVB=)の実際の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%同じです。
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は、typedef
エイリアスを介してImport
の原始的な種類を知っています。
Imports S = System.String
Dim x As S = "Hello"
これは、ジェネリック型と組み合わせて使用するとより便利です。
Imports StringPair = System.Collections.Generic.KeyValuePair(Of String, String)
ああ! XML Literals を忘れないでください。
Dim contact2 = _
<contact>
<name>Patrick Hines</name>
<%= From p In phoneNumbers2 _
Select <phone type=<%= p.Type %>><%= p.Number %></phone> _
%>
</contact>
オブジェクトの初期化もそこにあります!
Dim x as New MyClass With {.Prop1 = foo, .Prop2 = bar}
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などのより柔軟な変換演算子を使用することもできます。
(Zackによる編集:詳細はこちら: VB.NETでのキャスト方法 )
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)
_
これはいいものです。 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
最高で簡単なCSVパーサー:
Microsoft.VisualBasic.FileIO.TextFieldParser
Microsoft.VisualBasicへの参照を追加することにより、これを他の.Net言語で使用できます。 C#
私がいつも使っている大きな時間節約の1つは、Withキーワードです。
With ReallyLongClassName
.Property1 = Value1
.Property2 = Value2
...
End With
必要以上に入力するのは好きではありません!
(編集:詳細はこちら: AndAlso演算子とOrElse演算子を常に使用する必要がありますか? )
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
メソッドの静的メンバー
例えば:
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メンバーとして宣言するのと同じではありません。この方法で宣言されたアイテムは、スレッドセーフであることが保証されています。このシナリオでは、式は決して変更されないため問題ではありませんが、他の場合には変更される可能性があります。
Visual Basic 2005で導入された"My"名前空間が本当に好きです。Myは、いくつかの情報グループへのショートカットですおよび機能。次の種類の情報にすばやく直感的にアクセスできます。
あまり有用ではありませんが、イベント処理は大幅にカスタマイズできます。
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は「辞書検索演算子」です。辞書は、英語の辞書のエントリが定義する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つの識別子が有効な場所がないため、!の後の次の文字がは識別子の始まりで、!型文字ではなく演算子になります。
これは組み込みであり、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
キーワードの変数名と一致する変数名が必要な場合は、括弧で囲みます。必要ないしかし、ベストプラクティス-しかし、それは賢明に使用することができます。
例えば.
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
インポートエイリアスもほとんど不明です。
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.aspxhttp://blogs.msdn.com/vbteam/archive/2009/09/25/ testing-events-for-nothing-null-doug-rothaus.aspx
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>
タグを使用する必要はありません。好きなタグを使用できます。)
1行で2行のコードを使用できます。したがって:
Dim x As New Something : x.CallAMethod
DateTimeは、日付を#で囲むことで初期化できます
Dim independanceDay As DateTime = #7/4/1776#
この構文とともに型推論を使用することもできます
Dim independanceDay = #7/4/1776#
それは、コンストラクタを使用するよりもずっといいです
Dim independanceDay as DateTime = New DateTime(1776, 7, 4)
オプションのパラメーター
オプションは、次のような新しいオーバーロードを作成するよりもはるかに簡単です。
Function CloseTheSystem(Optional ByVal msg AS String = "Shutting down the system...")
Console.Writeline(msg)
''//do stuff
End Function
ステートメントを一緒に使用して複数のスタック/グループ:
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#でも実行できます。しかし、多くの人はどちらの言語でもこれについて知りません。
VB.Netのタイトルケースは、古いVB6 fxnによって実現できます。
StrConv(stringToTitleCase, VbStrConv.ProperCase,0) ''0 is localeID
パラメータ付きのプロパティ
私はいくつかの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
多くのバグを解決するのに非常に役立ち、助けとなった機能の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)
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
次のことを知らなかった場合、本当にそうだとは思わないでしょう。これは、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をご覧ください。
1行にIfを含めることができます。
If True Then DoSomething()
これは私が見たことのない面白いものです。私はそれがVS 2008で動作することを知っています、少なくとも:
誤ってVBセミコロンを含む行を終了した場合、C#を実行しすぎているため、セミコロンは自動的に削除されます。実際に(少なくともVS 2008では)少なくともVB行をセミコロンで終了することはできません。試してください!
(完全ではありません。最終クラス名の途中でセミコロンを入力すると、クラス名はオートコンプリートされません。)
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
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())
両方の値がロードされたことを確認できます。
名前を[と]で囲むと、プロパティと変数名に予約キーワードを使用できます
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
Parsa's answerと同様に、 like operator にはlotsが一致するものがあり、上記の単純なワイルドカード。 MSDN docoを読んで、椅子から落ちそうになりました:-)
VB8および以前のバージョンでは、導入する変数に型を指定しなかった場合、オブジェクト型は自動的に検出されました。 VB9(2008)では、Option InferがOn(デフォルト)に設定されている場合、Dim
はC#のvar
キーワードのように動作します。
複数の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
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
完全な構文を使用することで、将来コードを読む人に、自分が何をしていたかを知っていることを示すこともできます。
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
VB.NETプロジェクトは、デフォルトで、プロジェクトのプロパティの一部であるルート名前空間を持っていることを覚えておくことも重要です。デフォルトでは、このルート名前空間はプロジェクトと同じ名前になります。 Namespaceブロック構造を使用する場合、名前は実際にそのルート名前空間に追加されます。たとえば、プロジェクトの名前がMyProjectの場合、変数を次のように宣言できます。
Private obj As MyProject.MyNamespace.MyClass
ルート名前空間を変更するには、[プロジェクト]-> [プロパティ]メニューオプションを使用します。ルート名前空間も同様にクリアできます。つまり、すべてのNamespaceブロックが含まれるコードのルートレベルになります。
MyClassキーワードは、派生クラスのオーバーライドを無視して、元の実装としてクラスインスタンスメンバーを参照する方法を提供します。
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
名前空間のエイリアス
Imports Lan = Langauge
VB.Netに固有のものではありませんが、名前空間の競合が発生すると忘れられることがよくあります。
VBはOnErrorステートメントも提供します。しかし、最近ではあまり役に立たない。
On Error Resume Next
' Or'
On Error GoTo someline
</ code>
「=」の代わりにREMを使用して行をコメントアウトできます。
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
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つの(おそらくそれ以上の)ことがあります。
また、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
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 でこの機能に投票してください。
あなたがそれをどのように非表示にするかわかりませんが、 If
演算子はカウントできます。
ある意味では、多くのCライクな言語の?:
(三項)または??
演算子に非常に似ています。ただし、すべてのパラメーターを評価することに注意することが重要です。そのため、例外が発生する可能性のあるもの(意図しない場合)または意図しない副作用を引き起こす可能性のあるものを渡さないことが重要です。
使用法:
Dim result = If(condition, valueWhenTrue, valueWhenFalse)
Dim value = If(obj, valueWhenObjNull)
以前はオプションの関数パラメーターが非常に好きでしたが、C#とVBを何度もやり直す必要があります。C#はいつサポートしますか? Cには(ある種の)それらがありました!
ByValとByRefキーワードの違い:
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
コードの文書化
''' <summary>
'''
''' </summary>
''' <remarks></remarks>
Sub use_3Apostrophe()
End Sub
いつかBasicユーザーは変数を導入しませんでした。彼らはそれらを使用するだけでそれらを紹介しました。 VBのOption Explicitは、不適切な入力によって誤って変数を導入しないようにするために導入されました。いつでもオフにして、Basicで作業した日々を体験できます。
再びオプションの引数!
Function DoSmtg(Optional a As string, b As Integer, c As String)
'DoSmtg
End
' Call
DoSmtg(,,"c argument")
DoSmtg(,"b argument")
メソッドの属性!たとえば、設計時に使用できないプロパティは、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、その特定のプロパティはそのカテゴリに表示されます。
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