Local variables within generic methods cannot be declared 'Static'?

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
 
A

Armin Zingler

PJ6 said:
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.

Your declaration is internally conceptually equal to:

Dim GetList_ret As New List(Of ItemType)

Public Function GetList(Of ItemType)() As List(Of ItemType)
Return GetList_ret
End Function

That means, the variable is actually a field of the class. Now it's obvious
why it can't work: The generic type 'ItemType' does not exist at class level
because the class is not a generic class, only the function is generic. So,
ItemType is unknown at class level.


Sorry, currently can't analyze your code example.


Armin
 
P

PJ6

Armin Zingler said:
Your declaration is internally conceptually equal to:

Dim GetList_ret As New List(Of ItemType)

Public Function GetList(Of ItemType)() As List(Of ItemType)
Return GetList_ret
End Function

That means, the variable is actually a field of the class. Now it's
obvious
why it can't work: The generic type 'ItemType' does not exist at class
level
because the class is not a generic class, only the function is generic.
So,
ItemType is unknown at class level.

*smacks head*... OK I see that now.

I'll have to wait until I can use the 3.5 framework and anonymous types
before I can simplify my design.

Thanks,
Paul
 
P

PJ6

PJ6 said:
*smacks head*... OK I see that now.

I'll have to wait until I can use the 3.5 framework and anonymous types
before I can simplify my design.

Actually scratch that I don't need 3.5... I'll just use IL.

I heard you can get something like a 50x performance gain in some cases,
too. Should be fun.

Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top