У меня есть функция, которая десериализует некоторые пользовательские сериализации, отправленные API.Я хочу построить универсальную функцию, чтобы десериализованный объект имел тип не Object
, а правильный тип.
Строки, содержащие сериализованный объект, можно десериализовать в один из следующих типов:
- A
String
, IList(Of String)
, IDictionnary(Of String)
, - один из множества
SomeNameContainer
классов, все производныеиз класса BaseContainer
, IList(Of SomeNameContainer)
или IDictionnary(Of SomeNameContainer)
.
Я хотел бы иметь один Function Deserialize(Of T)(MyString as String) as T
.Внутри этой функции я попытался выполнить несколько тестов Select Case T: GetType(String):Etc
, чтобы отделить различные действия для запуска на MyString
, в зависимости от ожидаемого объекта, который нужно создать от десериализации.
Например, десериализация вSomeNameContainer
обычно выполняется с помощью другой универсальной функции: Dim Deserialized as SomeNameContainer = GetFromContainer(SomeNameContainer)(MyString)
Однако я быстро ограничен, главным образом потому, что:
- Я не могу вернуть тип
String
, потому что онне может привести его к T. String
- тип значения, в то время как SomeNameContainer
- классы.Поэтому невозможно добавить ограничение (Of T As {New})
.Это означает, что я не могу сделать что-то вроде Dim NameContainer as New T: If TypeOf NameContainer Is BaseContainer
, чтобы применить одну и ту же операцию ко всем классам, производным от BaseContainer
.
Один трек, который я нашел, - это использование CTypeDynamic(Of T)(obj as object)
,который бросает во время выполнения.Это могло бы решить проблему 1, но проблема 2 все еще включена.
Function Deserialize(Of T)(MyString as String) as T
Select Case GetType(T)
Case GetType(String)
Return SomeFunction(String) '<- Only run-time casting allowed: Return CTypeDynamic(Of String)(SomeFunction(String))
Case GetType(IList(Of String)
Return SomeOtherFunction(String)
Case GetType(...)
'...
Case Else
Dim MyContainer as New T '<- Not Allowed to use New
if TypeOf MyContainer Is T then
Return GetFromContainer(Of T)(String)
else
'...
End If
End Select
End Function
Я мог бы решить разделить каждый Тип в отдельную функцию.Я хотел бы избежать, чтобы у меня не было 6 функций.Это потому, что мне также нужно выполнить некоторые другие операции над строкой перед ее десериализацией.Для истории строки подпадают под различные форматы кодирования / шифрования.Поэтому, если у меня есть 4 формата, то теперь мне нужно иметь дело с 4x6 = 24 функциями.
Я бы хотел иметь такую роскошь, как инкапсуляцию всего декодирования / десериализации в одну функцию: Dim MyObject as Something = Deserialize(Of Something)(StringFromAPI, MyEncodingEnumOptions.Option42)
Большое спасибо заранее!