Suppose I have the following class declaration:

    Public Class MyObjectR
        Private mStr As String
        Public Sub New(ByVal _Var1 As String)
            mStr = _Var1
        End Sub
        Public Property MyProperty As String
            Get
                Return mStr
            End Get
            Set(value As String)
                mStr = value
            End Set
        End Property
        Public Shared Widening Operator CType(ByVal _Initializer As String) As MyObjectR
            Return New MyObjectR(_Initializer)
        End Operator
    End Class

I can initialize an array of these, in this case conveniently using the widening operator to achieve a very readable initialization:

    Dim u As MyObjectR() = New MyObjectR() {"a", "b", "c", "d"}

At this point, I have an array of MyObjectR.

Suppose I now add the following class declaration to my scope:

    Public Class MyObjectS
        Private mStr As String
        Public Sub New(ByVal _Var1 As String)
            mStr = _Var1
        End Sub
    End Class

Now, I'd like to create and initialize a new array of MyObjectS with the same count as in my prior array of MyObjectR and where each MyObjectS is initialized by using a specific property of MyObjectR.

As implied in the following line of code (which isn't acceptable syntax for VB.NET):

    Dim v As MyObjectS() = New MyObjectS() {u.Select(Function(a) a.MyProperty)}

Here, I'd like to somehow use the iterator to feed successive use of the parameterized New of MyObjectS to create an array of them. Of course, the above line of syntax isn't correct.

(For anyone considering the idea, I need to add that I do NOT want to involve the use of widening operators here [even if possible] because MyObjectS might very well be a class object I don't control and also do not want to modify with methods. For example, it might be a ListViewItem [that does have a parameterized New accepting String.] So it's not necessarily an object of my own that I can tinker around with.)

Clearly, the syntax isn't quite as easy as I'd like to see in VB.NET. But I imagine that somewhere in VB.NET the syntax does exist and I'm simply ignorant about it.

Here's a different option I also tried without success (or expecting success):

    Dim v As MyObjectS() = New MyObjectS() {u.Select(Function(a) a.MyProperty).ToArray}

Just for completeness, I know I can easily do it this way:

    Dim w As List(Of MyObjectS) = New List(Of MyObjectS)
    For Each i As String In u.Select(Function(a) a.MyProperty)
        w.Add(New MyObjectS(i))
    Next
    Dim v As MyObjectS() = w.ToArray

But I'd like to learn any new syntax that may perform a similar operation without the need for creating a List(Of T) to do it. There are some good performance reasons, if no other.

1

There are 1 answers

0
Steve On BEST ANSWER

You need just one line of code

Dim v As MyObjectS() = u.Select(Function(a) New MyObjectS(a.MyProperty)).ToArray()

You simply ask the Select iterator to build a new MyObjectS for each element of the input sequence using the MyObjectR.MyProperty as parameter to MyObjectS constructor. At the end you can materialize the resulting sequence with ToArray.