私は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
Enum
_VBの本当の隠された機能の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はから可能な値のIntelliSenseリストを提供しますRuleTemplates
。
これはIDEに依存する機能であるため、使用したときにどのように見えるかを示すのは難しいですが、スクリーンショットを使用します。
実行中の完了リストhttp://page.mi.fu-berlin.de/krudolph/stuff/completionlist.png
実際、IntelliSenseは、を使用したときに得られるものと100%同じですEnum
。
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
viaImport
エイリアスを知っています。
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
演算子(演算子のオーバーロードを参照)を呼び出す必要がある場合にのみ呼び出す必要があります。
1)ガイドラインへのリンクを思い付くことができませんが、Paul Vickがそれを採用していることがわかりました(VBチームのチーフ開発者):
現実の世界では、違いに気付くことはほとんどないので、CType、CIntなどのより柔軟な変換演算子を使用することをお勧めします。
(Zackによる編集:詳細はこちら:VB.NETでどのようにキャストする必要がありますか?)
If
条件付き合体演算子あなたがそれをどれほど隠して呼ぶかはわかりませんが、Iif([expression]、[value if true]、[value if false])AsObject関数はカウントできます。
非推奨になるほど隠されていません!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 への参照を追加することで、C# などの他の .Net 言語で使用できます。
私が常に使用している主な時間節約の 1 つは、Withキーワードです。
With ReallyLongClassName
.Property1 = Value1
.Property2 = Value2
...
End With
必要以上にタイピングするのは好きではありません。
(編集: 詳細はこちら: AndAlso および OrElse 演算子を常に使用する必要がありますか? )
vb では、これらの演算子には違いがあります。
/
isDouble
\
は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の記事からの抜粋です。
!の技術名。演算子は「辞書検索演算子」です。辞書は、英語の辞書のエントリが定義したい単語によって索引付けされるのと同じように、数字ではなくキーによって索引付けされる任意のコレクションタイプです。ディクショナリタイプの最も一般的な例は、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番目の例は、最初の例と完全に同等ですが、少なくとも私の目には、はるかに見栄えがします。たくさんの場所があることがわかりました!特に、文字列でインデックス付けされたコレクションが大量にある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>
もちろん、タグを使用する必要はありません。好きなタグを使用できます。)
1 行に 2 行のコードを含めることができます。したがって:
Dim x As New Something : x.CallAMethod
DateTime は、日付を # で囲むことで初期化できます
Dim independanceDay As DateTime = #7/4/1776#
You can also use type inference along with this syntax
Dim independanceDay = #7/4/1776#
That's a lot nicer than using the constructor
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
パラメータ付きのプロパティ
私はいくつかのC#プログラミングを行っていて、VB.Netにはない機能を発見しましたが、ここでは言及されていません。
これを行う方法の例(およびc#の制限)は、次の場所にあります。C#での一般的なgetsetプロパティの使用...パラメーターを使用
私はその答えからコードを抜粋しました:
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
複数のusingステートメントを一緒にスタック/グループ化します。
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
私が非常に便利で、多くのバグの解決に役立った機能の 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)
次のことを知らなかった場合、それが本当だとは本当に信じられないでしょう。これは、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
BethMassiによるXMLLiteralsのヒント/コツをご覧ください。
If は 1 行で記述できます。
If True Then DoSomething()
when
行での使用に注意してくださいCatch ex As IO.FileLoadException When attempt < 3
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で最近見たもの
これは私が見たことのない面白いものです。少なくとも VS 2008 で動作することはわかっています。
C# を使いすぎたためにVB 行を誤ってセミコロンで終了した場合、セミコロンは自動的に削除されます。実際には (少なくとも VS 2008 では) VB 行を誤ってセミコロンで終了することは不可能です。それを試してみてください!
(完全ではありません。最終的なクラス名の途中でセミコロンを入力すると、クラス名がオートコンプリートされません。)
break
VB の C 言語とは異なり、次のことができ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
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
もちろん、これは完全に間違っています。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
完全な構文を使用することにより、将来コードを読む人に、自分が何をしているかを知っていることを示すこともできます。
複数の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
VB8以前では、導入した変数に型を指定しなければ、Object型が自動検出されていました。VB9 (2008) では、Option Infer が On (デフォルト) に設定されている場合、Dim
C# のキーワードのように動作します。var
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
VB.NET プロジェクトには、既定で、プロジェクトのプロパティの一部であるルート名前空間があることを覚えておくことも重要です。デフォルトでは、このルート名前空間はプロジェクトと同じ名前になります。Namespace ブロック構造を使用する場合、名前は実際にはそのルート名前空間に追加されます。たとえば、プロジェクトの名前が MyProject の場合、変数を次のように宣言できます。
Private obj As MyProject.MyNamespace.MyClass
ルート名前空間を変更するには、[プロジェクト] -> [プロパティ] メニュー オプションを使用します。ルート名前空間もクリアできます。つまり、すべての名前空間ブロックが含まれるコードのルート レベルになります。
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
このリンクが役立つかもしれません
http://blogs.msdn.com/vbteam/archive/2007/11/20/hidden-gems-in-visual-basic-2008-amanda-silver.aspx
MyClass キーワードは、派生クラスのオーバーライドを無視して、最初に実装されたクラス インスタンス メンバーを参照する方法を提供します。
VB には、OnError ステートメントも用意されています。しかし、最近ではあまり役に立ちません。
On Error Resume Next
' Or'
On Error GoTo someline
名前空間のエイリアス
Imports Lan = Langauge
VB.Net に固有のものではありませんが、名前空間の競合が発生すると忘れられることがよくあります。
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
' の代わりに REM を使用して行をコメントアウトできます。あまり便利ではありませんが、「!!!!!!!」を使用せずに重要なコメントを目立たせるのに役立ちます または何でも。
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
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# では、それについて夢見ることができます (現在、彼らは dynamic キーワードを作成しましたが、VB からはかけ離れています)。C# で (new object()).Enabled と記述すると、オブジェクト型にメソッド 'Enabled' がないというエラーが発生します。さて、これが安全かどうかをお勧めするのは私ではありません。情報はそのまま提供されます。自分で行ってください。バスはまだあります。時には (COM オブジェクトを操作するときなど)、これはとても良いことです。個人的には、期待値が確かにボタンの場合は必ず (sender As Button) と書きます。
さらに、次の例を見てください。
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
あなたがそれをどの程度隠していると呼ぶかはわかりませんが、If
オペレーターは数えることができます.
ある意味で、多くの C ライクな言語の?:
(三項) または演算子に非常に似ています。??
ただし、すべてのパラメーターを評価することに注意することが重要です。そのため、例外を引き起こす可能性のあるもの (必要な場合を除きます) や、意図しない副作用を引き起こす可能性のあるものを渡さないことが重要です。
使用法:
Dim result = If(condition, valueWhenTrue, valueWhenFalse)
Dim value = If(obj, valueWhenObjNull)
以前はオプションの関数パラメーターが非常に好きでしたが、C#とVBの間を頻繁に行き来する必要があるため、今ではあまり使用していません。C#はいつそれらをサポートしますか?C ++とCでさえ(ある種の)それらを持っていました!
コードのドキュメント
''' <summary>
'''
''' </summary>
''' <remarks></remarks>
Sub use_3Apostrophe()
End Sub
いつの日か、基本ユーザーは変数を導入しませんでした。使うだけで紹介してくれました。VB の Option Explicit は、間違った入力によって誤って変数を導入しないようにするために導入されました。いつでもオフにして、ベーシックで働いていた日々を体験してください。
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
再びオプションの引数!
Function DoSmtg(Optional a As string, b As Integer, c As String)
'DoSmtg
End
' Call
DoSmtg(,,"c argument")
DoSmtg(,"b argument")
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
メソッドの属性!たとえば、設計時に使用できないプロパティは、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()
も非常に役立ちます(関数内などにブレークポイントを配置することはできますが、その関数をシングルステップで実行することはできないことに注意してください)。
また、項目をカテゴリ (「データ」など) に配置できるということは、プロパティ ツール ウィンドウにプロパティを表示したい場合、その特定のプロパティがそのカテゴリに表示されることを意味します。
私のキーワード
"Me" キーワードは VB.Net で一意です。私はそれがかなり一般的であることを知っていますが、「Me」と C# に相当する「this」には違いがあります。違いは、"this" は読み取り専用で、"Me" は読み取り専用ではないことです。これは、変数の各フィールドを手動でコピーする必要がある C# とは対照的に、"Me = TheVariable" を設定するだけでよいため、構築される変数のインスタンスがあるコンストラクターで価値があります (多くのフィールドがあり、エラーが発生しやすい場合は恐ろしいことになる可能性があります)。C# の回避策は、コンストラクターの外部で割り当てを行うことです。つまり、オブジェクトが完全なオブジェクトに自己構築する場合、別の関数が必要になります。