P
PJ6
This doesn't work, at least in the 2.0 Framework which I am constrained to
that at the moment -
Public Function GetList(Of ItemType)() As List(Of ItemType)
Static ret As New List(Of ItemType)
Return ret
End Function
I would ask why, but the answer will either be 1. it's just not supported
yet, or 2. there is something fundamentally wrong with supporting it that's
not obvious to me.
Anyway - it is critical that the List(Of ItemType) function in the
ZoneListsCollection class below is high performance. That's why it's
generic; there must be no casting involved.
This is the only way I could find to serve generic anything without casting
within a class that has not been generically declared itself. I don't like
it because it 1. requires a lookup from a dictionary, and 2. if I don't want
a memory leak I will have to manually dispose any ZoneListsCollection when
I'm done with it.
Is there another way to do this?
Paul
--------------
Public Interface IZone(Of ItemType)
Function Contains(ByVal Item As ItemType) As Boolean
End Interface
Public Class ZoneListsCollection
Implements IDisposable
Private Const b As BindingFlags = BindingFlags.NonPublic Or
BindingFlags.Instance
Private Shared ReadOnly MyType As Type = GetType(ZoneListsCollection)
Private Shared ReadOnly IZoneType As Type = GetType(IZone(Of ))
Private _Zones As New List(Of Object)
Public Sub Add(ByVal Zone As Object)
_Zones.Add(Zone)
For Each i As Type In DirectCast(Zone, Object).GetType.GetInterfaces
If i.IsGenericType AndAlso i.GetGenericTypeDefinition Is IZoneType Then
Dim m As MethodInfo = _AddMethod.MakeGenericMethod(New Type()
{i.GetGenericArguments(0)})
m.Invoke(Me, b, Nothing, New Object() {Zone}, Nothing)
End If
Next
End Sub
Public Sub Remove(ByVal Zone As Object)
_Zones.Remove(Zone)
Dim t As Type = DirectCast(Zone, Object).GetType
For Each i As Type In t.GetInterfaces
If i.IsGenericType AndAlso i.GetGenericTypeDefinition Is IZoneType Then
Dim m As MethodInfo = _RemoveMethod.MakeGenericMethod(New Type()
{i.GetGenericArguments(0)})
m.Invoke(Me, b, Nothing, New Object() {Zone}, Nothing)
End If
Next
End Sub
Public Sub Clear()
For Each z As Object In _Zones
Remove(z)
Next
End Sub
Private Shared ReadOnly _AddMethod As MethodInfo = MyType.GetMethod("_Add",
b)
Private Sub _Add(Of ItemType)(ByVal zone As IZone(Of ItemType))
Dim mydata As Dictionary(Of IZone(Of ItemType), List(Of ObjectContainer(Of
ItemType))) = Nothing
If Not _ZoneLists(Of ItemType).Data.TryGetValue(Me, mydata) Then
mydata = New Dictionary(Of IZone(Of ItemType), List(Of ObjectContainer(Of
ItemType)))
_ZoneLists(Of ItemType).Data.Add(Me, mydata)
End If
mydata.Add(zone, New List(Of ObjectContainer(Of ItemType)))
End Sub
Private Shared ReadOnly _RemoveMethod As MethodInfo =
MyType.GetMethod("_Remove", b)
Private Sub _Remove(Of ItemType)(ByVal zone As IZone(Of ItemType))
_ZoneLists(Of ItemType).Data.Item(Me).Remove(zone)
If _ZoneLists(Of ItemType).Data.Item(Me).Count = 0 Then
_ZoneLists(Of ItemType).Data.Remove(Me)
End If
End Sub
Private Class _ZoneLists(Of ItemType)
Public Shared ReadOnly Data As New Dictionary(Of ZoneListsCollection,
Dictionary(Of IZone(Of ItemType), List(Of ObjectContainer(Of ItemType))))
End Class
Public Function List(Of ItemType)() As Dictionary(Of IZone(Of ItemType),
List(Of ObjectContainer(Of ItemType)))
Return _ZoneLists(Of ItemType).Data.Item(Me)
End Function
Private disposedValue As Boolean = False
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
Me.Clear()
End If
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable
pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As
Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
that at the moment -
Public Function GetList(Of ItemType)() As List(Of ItemType)
Static ret As New List(Of ItemType)
Return ret
End Function
I would ask why, but the answer will either be 1. it's just not supported
yet, or 2. there is something fundamentally wrong with supporting it that's
not obvious to me.
Anyway - it is critical that the List(Of ItemType) function in the
ZoneListsCollection class below is high performance. That's why it's
generic; there must be no casting involved.
This is the only way I could find to serve generic anything without casting
within a class that has not been generically declared itself. I don't like
it because it 1. requires a lookup from a dictionary, and 2. if I don't want
a memory leak I will have to manually dispose any ZoneListsCollection when
I'm done with it.
Is there another way to do this?
Paul
--------------
Public Interface IZone(Of ItemType)
Function Contains(ByVal Item As ItemType) As Boolean
End Interface
Public Class ZoneListsCollection
Implements IDisposable
Private Const b As BindingFlags = BindingFlags.NonPublic Or
BindingFlags.Instance
Private Shared ReadOnly MyType As Type = GetType(ZoneListsCollection)
Private Shared ReadOnly IZoneType As Type = GetType(IZone(Of ))
Private _Zones As New List(Of Object)
Public Sub Add(ByVal Zone As Object)
_Zones.Add(Zone)
For Each i As Type In DirectCast(Zone, Object).GetType.GetInterfaces
If i.IsGenericType AndAlso i.GetGenericTypeDefinition Is IZoneType Then
Dim m As MethodInfo = _AddMethod.MakeGenericMethod(New Type()
{i.GetGenericArguments(0)})
m.Invoke(Me, b, Nothing, New Object() {Zone}, Nothing)
End If
Next
End Sub
Public Sub Remove(ByVal Zone As Object)
_Zones.Remove(Zone)
Dim t As Type = DirectCast(Zone, Object).GetType
For Each i As Type In t.GetInterfaces
If i.IsGenericType AndAlso i.GetGenericTypeDefinition Is IZoneType Then
Dim m As MethodInfo = _RemoveMethod.MakeGenericMethod(New Type()
{i.GetGenericArguments(0)})
m.Invoke(Me, b, Nothing, New Object() {Zone}, Nothing)
End If
Next
End Sub
Public Sub Clear()
For Each z As Object In _Zones
Remove(z)
Next
End Sub
Private Shared ReadOnly _AddMethod As MethodInfo = MyType.GetMethod("_Add",
b)
Private Sub _Add(Of ItemType)(ByVal zone As IZone(Of ItemType))
Dim mydata As Dictionary(Of IZone(Of ItemType), List(Of ObjectContainer(Of
ItemType))) = Nothing
If Not _ZoneLists(Of ItemType).Data.TryGetValue(Me, mydata) Then
mydata = New Dictionary(Of IZone(Of ItemType), List(Of ObjectContainer(Of
ItemType)))
_ZoneLists(Of ItemType).Data.Add(Me, mydata)
End If
mydata.Add(zone, New List(Of ObjectContainer(Of ItemType)))
End Sub
Private Shared ReadOnly _RemoveMethod As MethodInfo =
MyType.GetMethod("_Remove", b)
Private Sub _Remove(Of ItemType)(ByVal zone As IZone(Of ItemType))
_ZoneLists(Of ItemType).Data.Item(Me).Remove(zone)
If _ZoneLists(Of ItemType).Data.Item(Me).Count = 0 Then
_ZoneLists(Of ItemType).Data.Remove(Me)
End If
End Sub
Private Class _ZoneLists(Of ItemType)
Public Shared ReadOnly Data As New Dictionary(Of ZoneListsCollection,
Dictionary(Of IZone(Of ItemType), List(Of ObjectContainer(Of ItemType))))
End Class
Public Function List(Of ItemType)() As Dictionary(Of IZone(Of ItemType),
List(Of ObjectContainer(Of ItemType)))
Return _ZoneLists(Of ItemType).Data.Item(Me)
End Function
Private disposedValue As Boolean = False
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
Me.Clear()
End If
End If
Me.disposedValue = True
End Sub
#Region " IDisposable Support "
' This code added by Visual Basic to correctly implement the disposable
pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As
Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class