I’m learning VB.NET and finding that there are dozens of ways to get the same behavior. So I’d like to know if there’s a better way to solve the following case.
Assume a simple interface and a class that implements it:
Public Interface IX
ReadOnly Property Name As String
End Interface
Public Class X
Implements IX
Public ReadOnly Property Name As String = "Hello" Implements IX.Name
End Class
Assume another interface and another class that implements it:
Public Interface IY
ReadOnly Property R As IEnumerable(Of IX)
End Interface
Public Class Y
Implements IY
Public Sub New(r As IEnumerable(Of IX))
mR = r.Select(Of X)(Function(a As IX, i As Integer) New X).Select(Of IX)(Function(a As X, i As Integer) a).ToList
End Sub
Protected mR As List(Of IX)
Public ReadOnly Property R As IEnumerable(Of IX) Implements IY.R
Get
Return mR
End Get
End Property
End Class
Then here’s three lines I’ll discuss:
Dim a As New List(Of IX) From {New X, New X}
Dim b As New Y(a)
Dim c As New Y(b.R)
What I want is for the first line to construct two X instances, then construct a List of just their interfaces. Then the second line should construct a Y instance using that List, but where the constructor will construct two more X instances to be copies of the original pair, which it will hold in its own instance. Then the third line does about the same, constructing a second Y instance, but this time using the list from b to do it — and yes, constructing two more X instances in the process.
By the end of those three statements I expect six instances of X to be floating around and two instances of Y. a will hold references to two of them. b will hold references to two more of them. And c will hold references to the last two of them.
The single line in the body of Y‘s constructor is a very long line. I iterate through each interface, make an X from it to get a new instance, then slice it back to just an interface, finally collecting up the entire iteration to make a List from it. I believe it does perform as described above. But I’m not sure if all of that is necessary.
Is there a preferred way to handle this? Is there something wrong with the way I handled it?
added for Craig’s comment below
I thought just as you did about the second Select
. And that is the first way I chose to write it. But as you can see:
the compiler/IDE doesn’t like it.
Apparently, it isn’t willing (probably for good reason) to take the assumption that a request to iterate through a bunch of X‘s to make a List of them can’t be automatically converted to a request to iterate through a bunch of interfaces of IX‘s to make a List of those, instead. I could pass an X as a parameter to a function expecting an IX. And that works, of course, as it should. But here? It doesn’t seem to want to go that far.
10