Home > OS >  Why Can't I Nest Collection Initializers For Custom Classes the Way I can for Dictionaries
Why Can't I Nest Collection Initializers For Custom Classes the Way I can for Dictionaries

Time:01-14

Background

I am using VB.Net, and trying to learn more about advanced classes. I've been experimenting with creating custom collection initializers. I have everything very close to working, but the last step is still not working and I can't figure out what piece I'm missing.

With a Dictionary(Of String, String) type, I can initialize it with the following code, which works perfectly:

Dim Test1 = New Dictionary(Of String, String) From {
    {"MyKey1", "MyValue1"}
    {"MyKey2", "MyValue2"}
}

Goal

I have a custom class, called IDOPropertyList, and I want to be able to initialize it the same way:

Dim Test3 = New IDOPropertyList From {
    {"MyKey1", "MyValue1"}
    {"MyKey2", "MyValue2"}
}

It isn't working.

What Is Working

Dim Test3 = New IDOPropertyList From {
    New IDOProperty From {"MyKey1", "MyValue1"}
    New IDOProperty From {"MyKey2", "MyValue2"}
}

My Two Custom Classes

Public Class IDOProperty
    Private ReadOnly Property _parts As New List(Of String)
    Public ReadOnly Property Name As String
        Get
            Return _parts(0)
        End Get
    End Property
    Public ReadOnly Property Value As String
        Get
            Return _parts(1)
        End Get
    End Property
    Public Function GetEnumerator() As IEnumerator(Of String)
        Return _parts.GetEnumerator
    End Function

    Public Sub Add(part As String)
        _parts.Add(part)
    End Sub
End Class

Public Class IDOPropertyList
    Private ReadOnly Property _IDOProperties As New List(Of IDOProperty)

    Public Function GetEnumerator() As IEnumerator(Of IDOProperty)
        Return _IDOProperties.GetEnumerator
    End Function

    Public Sub Add(IDOProperty As IDOProperty)
        _IDOProperties.Add(IDOProperty)
    End Sub

End Class

Question

What am I missing in order to be able to initialize my outer class the way that a dictionary can be initialized?

CodePudding user response:

Not sure whether this answers the question as expected, anyway, you could add a method to IDOPropertyList that accepts a ParamArray of String() elements.
Then each group of strings in:

{"MyKey1", "MyValue1"}, {"MyKey2", "MyValue2"}

is passed to the Add() method, in sequence:

If you then add an Operator to IDOProperty that converts a String() to itself, you get that result.
For example:

Public Class IDOProperty
    ' [...]

    Public Sub Add(part As String)
        _parts.Add(part)
    End Sub

    Public Shared Widening Operator CType(ByVal parts As String()) As IDOProperty
        If parts Is Nothing OrElse parts.Length <> 2 Then
            Throw New ArgumentException($"Invalid Argument. Expected 2 parts, got {If(parts Is Nothing, 0, parts?.Length)}")
        End If
        Return New IDOProperty() From {parts(0), parts(1)}
    End Operator
End Class

Public Class IDOPropertyList
    Private ReadOnly Property _IDOProperties As New List(Of IDOProperty)
    ' [...]

    Public Sub Add(IDOProperty As IDOProperty)
        _IDOProperties.Add(IDOProperty)
    End Sub
    Public Sub Add(ParamArray IDOProperty As String())
        _IDOProperties.Add(IDOProperty)
    End Sub
End Class

Now you can initialize IDOPropertyList with:

Dim ATest = New IDOPropertyList From {
    {"MyKey1", "MyValue1"},
    {"MyKey2", "MyValue2"}
}
  • Related