Visual Basic .NET Language Collection Initializer


Example

  • Arrays

     Dim names = {"Foo", "Bar"} ' Inferred as String()
     Dim numbers = {1, 5, 42} ' Inferred as Integer()
    
  • Containers (List(Of T), Dictionary(Of TKey, TValue), etc.)

     Dim names As New List(Of String) From {
         "Foo",
         "Bar"
         '...
     }
    
     Dim indexedDays As New Dictionary(Of Integer, String) From {
         {0, "Sun"},
         {1, "Mon"}
         '...
     }
    

    Is equivalent to

     Dim indexedDays As New Dictionary(Of Integer, String)
     indexedDays.Add(0, "Sun")
     indexedDays.Add(1, "Mon")
     '...
    

    Items can be the result of a constructor, a method call, a property access. It can also be mixed with Object initializer.

     Dim someList As New List(Of SomeClass) From {
         New SomeClass(argument),
         New SomeClass With { .Member = value },
         otherClass.PropertyReturningSomeClass,
         FunctionReturningSomeClass(arguments)
         '...
     }
    

    It is not possible to use Object initializer syntax AND collection initializer syntax for the same object at the same time. For example, these won't work

     Dim numbers As New List(Of Integer) With {.Capacity = 10} _
                                         From { 1, 5, 42 }
    
     Dim numbers As New List(Of Integer) From {
         .Capacity = 10,
         1, 5, 42
     }
    
     Dim numbers As New List(Of Integer) With {
         .Capacity = 10,
         1, 5, 42
     }
    
  • Custom Type

    We can also allow collection initializer syntax by providing for a custom type.
    It must implement IEnumerable and have an accessible and compatible by overload rules Add method (instance, Shared or even extension method)

    Contrived example :

     Class Person
         Implements IEnumerable(Of Person) ' Inherits from IEnumerable
    
         Private ReadOnly relationships As List(Of Person)
    
         Public Sub New(name As String)
             relationships = New List(Of Person)
         End Sub
    
         Public Sub Add(relationName As String)
             relationships.Add(New Person(relationName))
         End Sub
    
         Public Iterator Function GetEnumerator() As IEnumerator(Of Person) _
             Implements IEnumerable(Of Person).GetEnumerator
    
             For Each relation In relationships
                 Yield relation
             Next
         End Function
    
         Private Function IEnumerable_GetEnumerator() As IEnumerator _ 
             Implements IEnumerable.GetEnumerator
    
             Return GetEnumerator()
         End Function
     End Class
    
     ' Usage
     Dim somePerson As New Person("name") From {
         "FriendName",
         "CoWorkerName"
         '...
     }
    

    If we wanted to add Person object to a List(Of Person) by just putting the name in the collection initializer (but we can't modify the List(Of Person) class) we can use an Extension method

     ' Inside a Module
     <Runtime.CompilerServices.Extension>
     Sub Add(target As List(Of Person), name As String)
         target.Add(New Person(name))
     End Sub
    
     ' Usage
     Dim people As New List(Of Person) From {
         "Name1", ' no need to create Person object here
         "Name2"
     }