初期化の書き方いろいろ
初期化する際、頻度が多く使いそうなものをピックアップしておきたいと思います。
目次
単一データ
下から順に丁寧な書き方になります。調べ物の確認やプライベートなものを作ろうとした場合、一番下のように型推論に任せっきりの手抜きになります。変数名だけで分かるでしょ?みたいな。
Dim _1 As Class1 = New Class1 Dim _2 As New Class1 Dim _3 = New Class1 Dim name = "taro"
単一データ、オブジェクト初期化子
従来だとインスタンス生成とプロパティの設定は別々に記載していましたが、オブジェクト初期化子を使うことで、公開プロパティに限りクラス、または構造体に対して、インスタンス生成と同時に、各プロパティに初期値をセットすることができます。
Class Class1 Public Property Name As String Public Property Age As Integer End Class Structure Structure1 Public Property Name As String Public Property Age As Integer End Structure Module Module1 Sub Main() Dim obj1 As New Class1 obj1.Name = "taro" obj1.Age = 23 Dim obj2 As New Class1 With {.Name = "taro", .Age = 23} Dim obj3 = New Structure1 With {.Name = "taro", .Age = 23} Console.ReadKey() End Sub End Module
少し細かく見ていきます。こういう場合は、どうなるのでしょうか?
Class Class1 Public Property Name As String = "taro" Public Property Age As Integer = 22 Public Sub New() End Sub Public Sub New(name As String, age As Integer) Me.Name = name Me.Age = age End Sub Public Overrides Function ToString() As String Return $"{NameOf(Me.Name)} = {Me.Name}, {NameOf(Me.Age)} = {Me.Age}" End Function End Class Module Module1 Sub Main() Dim obj1 As New Class1("jiro", 25) With {.Name = "hanako", .Age = 32} Dim obj2 As New Class1("jiro", 25) Dim obj3 As New Class1() With {.Name = "hanako", .Age = 32} Dim obj4 As New Class1() Console.WriteLine(obj1) Console.WriteLine(obj2) Console.WriteLine(obj3) Console.WriteLine(obj4) Console.ReadKey() End Sub End Module
出力結果
Name = hanako, Age = 32 Name = jiro, Age = 25 Name = hanako, Age = 32 Name = taro, Age = 22
答えは、インスタンス生成処理→オブジェクト初期化子の順番で処理が進んでいくので、後付けの設定値が優先されます。
- プロパティに初期値をセット
- コンストラクタ内で指定したプロパティに、値を上書きセット
- オブジェクト初期化子で指定したプロパティに、値を上書きセット
コレクションデータ
こちらも同様に、下から順に丁寧な書き方になります。配列の場合、カッコを変数名につけるか型名に付けるか、どちらでも変わらないみたいですが、個人的には変数名にくっつけたほうがこの変数が配列だと見てわかるので前につけるかなぁ。リストは、できるだけジェネリックリストの方を積極的に使っていきたいですね。
' 配列 Dim s1 As String() = New String() {"a", "b"} Dim s2() As String = {"a", "b"} Dim s3() = {"a", "b"} ' リスト Dim lst1 As ArrayList = New ArrayList(New String() {"a", "b"}) Dim lst2 As New ArrayList(New String() {"a", "b"}) Dim lst3 = New ArrayList(New String() {"a", "b"}) Dim lst4 As List(Of String) = New List(Of String)(New String() {"a", "b"}) Dim lst5 As New List(Of String)(New String() {"a", "b"}) Dim lst6 = New List(Of String)({"a", "b"}) ' シーケンス Dim seq1 As IEnumerable(Of Integer) = Enumerable.Range(1, 10) Dim seq2 = Enumerable.Range(1, 10)
コレクションデータ、コレクション初期化子
コレクション初期化子はコレクションなら全てで使えるわけではありませんが、少なくともリスト系なら使えます。ディクショナリ系にも使えます。
' リスト Dim lst1 As List(Of String) = New List(Of String)(New String() {"a", "b"}) Dim lst2 As New List(Of String)(New String() {"a", "b"}) Dim lst3 = New List(Of String)({"a", "b"}) Dim lst4 As List(Of String) = New List(Of String) From {"a", "b"} Dim lst5 As New List(Of String) From {"a", "b"} Dim lst6 = New List(Of String) From {"a", "b"} ' ディクショナリ Dim dic1 As New Dictionary(Of Integer, String) dic1.Add(0, "taro") dic1.Add(1, "jiro") dic1.Add(2, "hanako") Dim dic2 As New Dictionary(Of Integer, String) From { {0, "taro"}, {1, "jiro"}, {2, "hanako"} }
特にリストはカッコの数が多くて、変数、型名、初期値、の区切りが分かりづらいです。なので、From キーワードがあるおかげで、見通しが良くなりました。後はこういう風にデータソースとして使うかなぁ。ちなみに、閉じ波かっこの位置を変えています。
Class Person Public Property Name As String Public Property Age As Integer End Class Module Module1 Sub Main() Dim items = New List(Of Person) From { New Person With {.Name = "taro", .Age = 22}, New Person With {.Name = "jiro", .Age = 25}, New Person With {.Name = "hanako", .Age = 32} } Dim hanako = items. Where(Function(x) x.Name.Contains("a")). Where(Function(x) 30 < x.Age). Select(Function(x) x.Name). FirstOrDefault() Console.ReadKey() End Sub End Module
最後に
見やすいコード、少ないコードが一番いいよね。