Duncan Edwards Jones Ответов: 1

Сделайте универсальный экземпляр giveh тип (не экземпляр)


У меня есть универсальный класс, используемый для сериализации события в/из словаря пар имя-значение. Он имеет следующую сигнатуру класса:-

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


У него есть фабричный метод, который может создать его из экземпляра класса таким образом:-
    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


Как бы я сделал фабричный метод, который мог бы создать сериализатор, если бы это была система?Параметр типа передается в :-

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


?

Что я уже пробовал:

Создание экземпляра типа с помощью отражения работает, но не является ни элегантным, ни действительно правильным..

1 Ответов

Рейтинг:
5

Richard Deeming

Вам понадобится не универсальный базовый класс или интерфейс, содержащий члены вашего класса, которые не полагаются на параметр универсального типа.

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

Возможно, вы захотите кэшировать MethodInfo для универсального метода в общем поле, чтобы избежать накладных расходов на его поиск каждый раз, когда вы вызываете не универсальный заводской метод.


Maciej Los

5ed!