Visual Basic 2010 の新機能





今回は、Visual Basic 2010の新機能の中から、以下のものについてご紹介します。


l   コレクション初期化子 (Collection Initializers)


l   共変性 (Covariance) / 反変性 (Contravariance)


詳細については、以下の資料をご参照ください。


l   CTPウォークスルードキュメント


https://connect.microsoft.com/VisualStudioJapan/content/content.aspx?ContentID=10212


l   New Features in Visual Basic 10 Document (英語)


http://code.msdn.microsoft.com/vbfuture/Release/ProjectReleases.aspx?ReleaseId=1699


 


コレクション初期化子


コレクション初期化子を利用すると、コレクションのコンストラクターを呼び出す際に、以下のように略された構文でAddを何回でも呼び出せます。


 


Dim list As New ArrayList() From {1, 2, 3}


 


ご存知のように、メソッドの種類には普通のメソッドと拡張メソッドの2つがあります(拡張メソッドはVB2008で新たに導入されました)。ArrayListAddメソッドは普通のメソッドですが、以下の例のように、Addが拡張メソッドであっても、コレクション初期化子を利用することができます。


以下の例は、新しく片方向リスト(Single Linked List)を作成して、1から4までの数字を入れるものです。


 


Imports System.Runtime.CompilerServices


 


Class SingleLinkedList (Of T)


    Implements IEnumerable(Of T)


 


    Public Tail As SingleLinkedList (Of T)


    Public Head As T


 


    Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator


        ' ...


    End Function


 


    Public Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator


        ' ...


    End Function


End Class


 


Module Module1


    <Extension()>


    Public Sub Add(Of T)(ByRef coll As SingleLinkedList (Of T), ByVal elem As T)


        Dim newColl As New SingleLinkedList (Of T) With {.Head = elem, .Tail = coll}


        coll = newColl


    End Sub


 


    Sub Main()


        Dim x As New SingleLinkedList (Of Integer) From {1, 2, 3, 4}


    End Sub


End Module


 


尚、Module1Addメソッドの引数collByRefで渡されるために、コレクション初期化子経由でAddを呼ぶとコレクションのリファレンスが変更されることになります。


 


次の例のように、Addは複数の引数を受けることも出来ます。そのようにするとSystem.Collections.Generic.Dictionaryのような型に対してもコレクション初期化子が使えます:


 


Dim x = New Dictionary(Of Integer, String)() From {{10, "101"}, {20, "202"}}


 


共変性 / 反変性


VB2008では下記のコードがコンパイルできません。なぜならば、「足を数える」関数には IEnumerable(Of 動物) を渡す必要がありますが、Mainで宣言された「私の哺乳動物」はIEnumerable(Of 哺乳動物)なので、型の間に互換性がないからです。


 


Class 動物


    Public Property 足の数 As Integer


End Class


 


Class 哺乳動物


    Inherits 動物


End Class


 


Module Module1


    Public Function 足を数える(ByVal coll As IEnumerable(Of 動物)) As Integer


        Dim count = 0


 


        For Each a In coll


            count += a.足の数


        Next


 


        Return count


    End Function


 


    Sub Main()


        Dim 私の哺乳動物 As New List(Of 哺乳動物)() From {}


 


        足を数える(私の哺乳動物)


    End Sub


End Module


 


しかし、哺乳動物も動物なので、「足を数える」関数を哺乳動物にも使いたいと思うのではないでしょうか。VB2010では、以下のようにIEnumerable(Of T)の宣言が新機能の共変性を使うようになり、VBコンパイラーが共変性・反変性をサポートするようになったので、それが出来るようになり、上記のサンプルコードも正しくコンパイルされるようになりました。


 


Interface IEnumerable(Of Out T) : Inherits IEnumerable


    Function GetEnumerator() As IEnumerator(Of T)


End Interface


 


.NETの共変性というのは、例えば、coll As IEnumerable(Of 動物) の代わりに IEnumerable(Of 哺乳動物) を渡すように、より具体的なジェネリックの引数の型を渡すことです。


 


反変性はその逆になります。例えば、IComparer (Of オカメインコ) の代わりにIComparer (Of ペット)を渡します。オカメインコはペットの一種なので、オカメインコをIComparerで比較しているということは、つまりはペットを比較していることになるからです。


下記は反変性のサンプルコードです。


 


Class ペット


    Public Name As String


End Class


 


Class 名前によって比較


    Implements IComparer(Of ペット)


    ' ...


End Class


 


Class


    Inherits ペット


End Class


 


Class オカメインコ


    Inherits ペット


End Class


 


Module Module1


    Sub Main()


        Dim 犬の名簿 As New SortedList(Of , Object)(New 名前によって比較)


        Dim オカメインコの名簿 As New SortedList(Of オカメインコ, Object)(New 名前によって比較)


    End Sub


End Module


 


VS2008以前はSortedListのコンストラクターそれぞれにIComparer(Of ) または IComparer(Of オカメインコ)を渡す必要がありましたが、反変性を利用するとIComparer(Of ペット) を渡すことが出来るようになります。


 


共変性 / 反変性自体は2005年頃からCLRでサポートされていましたが、VB2010C2010で実際にサポートされるまでは利用できませんでした。


Skip to main content