Generic variance and List(Of T)
Posted
Fri, Aug 8 2008 15:55
by
bill
This post has been sitting in my drafts for a while, so I thought I should post it, mainly because I want to talk about this and generic variance and arrays in more detail in the days ahead. The reason this post was put on hiatus was I was waiting for my article on arrays to appear in Visual Studio Magazine, as that deals with many of the details as to why this works ;)
Have you ever wanted to cast a List(Of Customer) to a List(Of BusinessBase), where Customer Inherits BusinessBase, only to find that you can't... well you can ;)
This extension will return an IList of BusinessBase for an input of a List(Of Customer). Be aware it is the underlying array, so you will need to get the actual count from the original input.
<Runtime.CompilerServices.Extension()> _
Function ToIList(Of T, TBase)(ByVal list As List(Of T)) As IList(Of TBase)
Dim fi = GetType(List(Of T)).GetField("_items", Reflection.BindingFlags.Instance Or _
Reflection.BindingFlags.GetField Or _
Reflection.BindingFlags.NonPublic)
Return CType(fi.GetValue(list), IList(Of TBase))
End Function
And a quick test:
Module Module1
Sub Main()
Dim myApples As New List(Of Apple)
myApples.Add(New Apple With {.Name = "Golden Delicious"})
myApples.Add(New Apple With {.Name = "Red Delicious"})
myApples.Add(New Apple With {.Name = "Granny Smith"})
Dim fruits As IList(Of Fruit) = myApples.ToIList(Of Fruit)()
For i = 0 To myApples.Count - 1
fruits(i).Name = "Fruit : " & fruits(i).Name
Next
For Each a In myApples
Console.WriteLine(a.Name)
Next
Console.WriteLine("finished")
Console.ReadLine()
End Sub
<Runtime.CompilerServices.Extension()> _
Function ToIList(Of T, TBase)(ByVal list As List(Of T)) As IList(Of TBase)
Dim fi = GetType(List(Of T)).GetField("_items", _
Reflection.BindingFlags.Instance Or _
Reflection.BindingFlags.GetField Or _
Reflection.BindingFlags.NonPublic)
Return CType(fi.GetValue(list), IList(Of TBase))
End Function
End Module
Class Fruit
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
End Class
Class Apple : Inherits Fruit
End Class