• 検索結果がありません。

Visual Basic 資料 電脳梁山泊烏賊塾 コレクション初期化子 コレクション初期化子 初めに.NET 版の Visual Basic では 其れ迄の Visual Basic 6.0 とは異なり 下記の例の様に変数宣言の構文に 初期値を代入する式が書ける様に成った 其の際 1 の様に単一の値

N/A
N/A
Protected

Academic year: 2021

シェア "Visual Basic 資料 電脳梁山泊烏賊塾 コレクション初期化子 コレクション初期化子 初めに.NET 版の Visual Basic では 其れ迄の Visual Basic 6.0 とは異なり 下記の例の様に変数宣言の構文に 初期値を代入する式が書ける様に成った 其の際 1 の様に単一の値"

Copied!
5
0
0

読み込み中.... (全文を見る)

全文

(1)

■ コレクション初期化子 ■ ■ 初めに

.NET 版の Visual Basic では、其れ迄の Visual Basic 6.0 とは異なり、下記の例の様に変数宣言の構文 に、初期値を代入する式が書ける様に成った。其の際、①の様に単一の値(此処では 10)を代入する丈 でなく、②の配列変数の宣言の様に、ブレース { } の中にカンマ区切りで初期値のリストを記述し、配 列の各要素に初期値を代入出来る様に成った。②の表現を使用すれば、要素の数丈代入文を書く必要も なくコードは簡潔に成り、配列の各要素の値を把握する上での可読性も向上する。

Dim x As Integer = 10 ←① Dim num() As Integer = { 10, 20, 30, 40, 50 } ←②

然して、Visual Basic 10.0(Visual Basic 2010)では、配列丈ではなくコレクションに付いても、コレ クション初期化子(Collection Initializer)と呼ばれる新しい構文を使用して、コレクションの各要素 への初期化を簡潔に表記出来る様に成った。此処では、此の新しい構文の基本的な使用方法の他、抑々 此の構文を使用出来るコレクションオブジェクトの要件は何で有るのかと謂う点や、カスタマイズを行 った応用例を取り上げる。 ■ コレクションの基本的な初期化 先ず、コレクション初期化子の基本的な使用方法を確認して見る。下記の例では、2 個のコレクション に対して、夫々初期値を代入して居る(此の構文は、Visual Studio 2008 の Visual Basic 9.0、及び其 れ以前のバージョンでは記述出来ない)。

Private Sub TestProc01()

Dim Col As New ArrayList() From {10, 20, 30} ←① Dim Lst As New List(Of Integer) From {10, 20, 30} ←② End Sub

①の ArrayList オブジェクトは、要素を Object 型として管理する汎用的なコレクションで有る。亦、 ②の List (Of Integer) はジェネリックを利用したコレクションで有る。ジェネリックに付いての詳細は 此処では割愛するが、(Of Integer) が要素の型を表して居る。詰まり、List (Of Integer) は Integer 型 の要素のコレクションで有る。 夫々のコレクションに関して、コレクション初期化子を使用した構文は次の形式に成る。 New コレクションクラス() From { 値 1, 値 2, 値 3, ... } 此の構文で、New キーワードの後にクラス名を記述してコレクションのオブジェクトインスタンスを作 成する点は従来の表記方法だが、其の後に From キーワードを続け、ブレース { } の中にカンマ区切り で各要素の初期値を書く事が出来る。特に、冒頭の配列変数の初期化と異なる点は、From キーワード が有る点で有る。此処では、上記の①と②の孰れも、順に 10、20、30 の値の要素がコレクションに追 加される。 此の初期化の表記方法は、実質的には下記の例の様に、其のコレクションの Add メソッドを呼び出して 要素を追加する方法と同等で有る。Add メソッドの引数には、コレクション初期化子の From キーワー ド以降に列挙された初期値のリスト(此処では、10、20、30)が順に渡されて居る。

コレ

レク

クシ

ショ

ョン

ン初

初期

期化

化子

(2)

Private Sub TestProc02() Dim Col As New ArrayList() Col.Add(10)

Col.Add(20) Col.Add(30)

Dim Lst As New List(Of Integer) Lst.Add(10) Lst.Add(20) Lst.Add(30) End Sub 上記の例の様に直接記述する場合は、明らかにステートメントの行数が増えて手間が懸かり、亦、前述 の例の方が端的に初期化したい内容が伝わり、可読性が高く成る。 ■ コレクションの 1 個の要素に対して複数の初期値を指定 結局の処、コレクション初期化子はコレクションの Add メソッドを介して要素を追加する事に成る。拠 って、Add メソッドの引数形式に応じて、初期値のリストの記述方法が変わる。此処で、初期値のリス トのバリエーションを確認して見る。

下記の例では、コレクションの一種で有る Dictionary (Of Integer, String) オブジェクトに対して、各 要素の初期化を行って居る。亦、其の次の例はと同等の追加操作を Add メソッドの呼び出しで表わした 物で有る。

Private Sub TestProc03()

Dim dict As New Dictionary(Of Integer, String) _

From {{100, "東地区"}, {200, "西地区"}, {300, "本部"}} ←① End Sub

Private Sub TestProc04()

Dim dict As New Dictionary(Of Integer, String) dict.Add(100, "東地区") ←② dict.Add(200, "西地区")

dict.Add(300, "本部") End Sub

上記の例に登場する Dictionary (Of Integer, String) オブジェクトは、1 個の要素がキーと値のペアで 構成されて居る。ディクショナリーは、特定のキーに対する値を求める時等に使用する。此の Dictionary (Of Integer, String) オブジェクトもジェネリックが使用されて居る。(Of Integer, String) の部分は、 キーが Integer 型で、値が String 型で有る事を表して居る。 此処では、1 個の要素が Integer 型と String 型の 2 個のデータのペアから構成されて居り、上例の②に 有る様に、此のコレクションの Add メソッドも 2 個の引数を持って居る。コレクション初期化子が此 れに対応する為には、①の様に括弧が入れ子に成り、要素毎にブレース { } を使用して、引数の並びを 構成する。詰まり、②の呼び出しの様に、引数に、100, "東地区" と 2 個の値を渡す為には、①の冒頭 に有る通り、下記の様な 2 個の値の並びを渡す。 { 100, "東地区" }

(3)

■ コレクション初期化子に対応するオブジェクトの要件

此処迄の処はコレクション初期化子の使用方法を確認したが、此処では、コレクション初期化子が使用 出来るオブジェクトの要件(即ち、オブジェクトインスタンスの作成時に From 句を使用して初期化の リストを記述出来るオブジェクトの要件)に付いて確認する。

Visual Basic 2010(Visual Basic 10.0)の言語仕様に依ると、コレクション初期化子に対応するオブジ ェクトは、下記の 2 個の条件を満たす必要が有る。

1.コレクション(collection type)で有る事

2.From 句の初期化のリストに対応した Add メソッドを持つ事

先ず、条件 1 に付いて確認する。Visual Basic の言語仕様では、コレクション(collection type)に付 いても定義が有り、IEnumerable インターフェイスを実装したオブジェクト等、幾つかの実装パターン が定義されて居る。簡単に謂うと、For Each...Next ループの In キーワードの後ろに記述出来る集合を 扱うオブジェクトと謂う事が出来る。 亦、Visual Studio 2010 以降のコードエディターで、コレクションクラスのインスタンスを作成するコ ードを入力する時、下図の様に入力候補(インテリセンス)の一覧には、From キーワードも列挙され るか何うか判断する事が出来る。 次に、条件 2 に付いて補足する。コレクション初期化子を使用する為には、コレクションと謂う条件 1 を満たした丈では不充分で有る。From キーワードの後に記述される初期化のリストを引数として受け 取れる適切な Add メソッドが必要で有る。下図は、コレクションで有る条件 1 を満たして居ても、適 切な Add メソッドが無い場合のエラー(波線)を表して居る。

(4)

上図の 2 個の赤い矢印の内、①のエラーは、Add メソッドの引数のパターンが合致していないエラーで 有る。既に述べた様に、Dictionary (Of Integer, String) オブジェクトの Add メソッドでは、2 個の引 数が必要だが、此の例では Integer 型の引数 1 個しか渡して居ない(メソッド 'Add' には、1 個の引数 を受け取るオーバーロードが有りません)。 一方、②では、MyCollection クラスが IEnumerable インターフェイスを実装して定義したオブジェク トだが、Add メソッドを定義して居ない為に発生するエラーで有る(型 'Project1.MyCollection' には、 アクセス可能な 'Add'メソッドがない為、…)。 ②においてコレクション初期化子を有効にするには、Integer 型の引数 1 個を持つ Add メソッドが必要 な為、MyCollection の定義に Add メソッド(①の部分)を追加する必要が有る。

Public Class MyCollection Implements IEnumerable

Public Function GetEnumerator1() As IEnumerator _ Implements IEnumerable.GetEnumerator

Return New MyEnumerator() End Function

Public Sub Add(ByVal dt As Integer) ←① ' End Sub End Class 此れで、カスタムオブジェクトをコレクション初期化子に対応出来る様に成る。 ■ コレクション初期化の為の使い勝手を良くするカスタマイズ 最後に、応用例を 1 個取り上げましょう。コレクションの各要素が、複数のプロパティを持つオブジェ クトで有る場合も有る。下記の例では、List (Of Product) と謂う型でコレクションを宣言して居る。詰 まり、"(Of Product)" と記述して有る事から、Product クラスのインスタンスがコレクションの各要素 になって居る。Product クラスの定義は、例 9 の通りで有る。

Private Sub TestProc05

Dim list5 As New List(Of Product) _ ←① From {New Product() With {.ID = 10, .Price = 200D}, ←② New Product() With {.ID = 20, .Price = 300D},

New Product() With {.ID = 30, .Price = 500D}} Ens Sub

Public Class Product

Public Property ID As Integer ←③ Public Property Price As Decimal

End Class

上例の Product クラスには、ID プロパティと Price プロパティの 2 個のプロパティが有る。③の様に プロパティの定義には、Visual Basic 2010 の新機能で有る Auto-Implemented Properties と呼ばれる プロパティの簡易表現を使用した。

(5)

New Product() With {.ID = 10, .Price = 200D }

※ 此の With に依るオブジェクト初期化子は、Visual Basic 2008 から導入された比較的新しい表現で 有る。

猶、上記の例の様に、此の様な初期化を 3 個書いても良いが、3 個のインスタンスの違いは、プロパテ ィの部分(ID プロパティと Price プロパティ)丈なので、工夫すると、下記の例の様に更に簡潔に成る。

Private Sub TestProc05

Dim list5 As New List(Of Product) _

From {{10, 200D}, {20, 300D}, {30, 500D}} Ens Sub

上記の様な記述を可能にするには、前述した様に、2 個のプロパティを引数として受け取る Add メソッ ドをコレクションに追加し、其の Add メソッドの中で Product インスタンスを作る様にすれば良い。 但し、List (Of Product) で使用されて居る List (Of 型) と謂う形式のジェネリッククラスは、クラスラ イブラリに定義されたクラスなので、此のクラスに Add メソッドを直接追加出来ない。此の様な既存ク ラスの定義を変更せずに Add メソッドを追加するので有れば、拡張メソッドを利用する。拠って、上記 の例の様にコレクション初期化子を使用出来る様にするには、List (Of Product) に適用可能な拡張メソ ッドとして、下記の Add メソッドを定義すれば良い。

Namespace MyUtility

Public Module ListProductExtensions

<System.Runtime.CompilerServices.Extension()>

Public Sub Add(ByVal list As List(Of Product), ←① ByVal id As Integer, ByVal price As Decimal) ←② list.Add(New Product() With {.ID = id, .Price = price}) End Sub

End Module

End Namespace

拡張メソッドの第 1 引数は、拡張対象と成るコレクション自体なので、①の様に List (Of Product) と 成る。Add メソッドに渡る実際の引数は、②に有る様に第 2 引数と第 3 引数に成る。此の拡張メソッド の定義をした後、前記の例のソースコードの先頭に、以下の Imports 文を追加する事で、拡張メソッド が利用出来る様に成り、其の結果、以下の①のコレクション初期化子が有効に成る。 Imports Project1.MyUtility … (省略)

Private Sub TestProc05

Dim list5 As New List(Of Product) _

From {10, 200D}, {20, 300D}, {30, 500D}} ←① Ens Sub

参照

関連したドキュメント

調査資料として映画『ハリー・ポッター」シリーズの全7作を初期、中期、後期に分け、各時

ると,之が心室の軍一期外牧縮に依るものであ る事が明瞭である.斯様な血堅の一時的急降下 は屡々最高二面時の初期,

 この論文の構成は次のようになっている。第2章では銅酸化物超伝導体に対する今までの研

私はその様なことは初耳であるし,すでに昨年度入学の時,夜尿症に入用の持物を用

婚・子育て世代が将来にわたる展望を描ける 環境をつくる」、「多様化する子育て家庭の

実際, クラス C の多様体については, ここでは 詳細には述べないが, 代数 reduction をはじめ類似のいくつかの方法を 組み合わせてその構造を組織的に研究することができる

下記の 〈資料 10〉 は段階 2 における話し合いの意見の一部であり、 〈資料 9〉 中、 (1)(2). に関わるものである。ここでは〈資料

早いもので、今日は1学期の終業式、この4ヶ月の間に子ど