Click here to Skip to main content
15,887,267 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a generic class used to serialise an event to/from a name-value pairs dictionary. It has the following class signature:-

VB
Public Class EventSerializer(Of TEvent As {New, IEvent})


It has a factory method that can create it from an instance of the class thus:-
VB
    Public Function Create(Of TEvent As {New, IEvent})(ByVal evt As TEvent) As EventSerializer(Of TEvent)
        Return Create(Of TEvent)()
    End Function

    Public Function Create(Of TEvent As {New, IEvent})() As EventSerializer(Of TEvent)
' creation happens here
    End Function


How would I go about making a factory method that could create the serializer if a System.Type parameter is passed in :-

VB
Public Function Create(ByVal evtType As System.Type) As EventSerializer(Of ?)


?

What I have tried:

Instantiating the type by reflection works but is not elegant nor really correct..
Posted
Updated 24-Oct-17 9:11am

1 solution

You'd need a non-generic base class or interface containing the members of your class which don't rely on the generic type parameter.
VB.NET
Public MustInherit Class EventSerializer
    ' Non-generic members here...
    
    Public Shared Function Create(Of TEvent As {New, IEvent})(ByVal evt As TEvent) As EventSerializer(Of TEvent)
        Return Create(Of TEvent)()
    End Function
    
    Public Shared Function Create(Of TEvent As {New, IEvent})() As EventSerializer(Of TEvent)
        ' Magic happens here...
    End Function
    
    Public Shared Function Create(ByVal evtType As Type) As EventSerializer
        Dim method As MethodInfo = GetType(EventSerializer).GetMethod("Create", BindingFlags.Public Or BindingFlags.Static, Nothing, Type.EmptyTypes, Nothing)
        Dim result As Object = method.MakeGenericMethod(evtType).Invoke(Nothing, Nothing)
        Return DirectCast(result, EventSerializer)
    End Function
End Class

Public Class EventSerializer(Of TEvent As {New, IEvent})
    Inherits EventSerializer
    
    ' Generic members here...
End Class

You might want to cache the MethodInfo for the generic method in a shared field, to avoid the overhead of finding it each time you call the non-generic factory method.
 
Share this answer
 
v2
Comments
Maciej Los 24-Oct-17 15:36pm    
5ed!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900