Сценарий - получение строки JSON из сети и десериализация ее в правильный соответствующий тип записи.F # десериализовать строку JSON в правильный тип записи
JSON, строка может быть либо:
(1) "{"a":"some text"}"
или
(2) "{"b":1}"
Значения могут отличаться, но формат полей будет либо соответствующая Type1 или типа 2:
type Type1 = {a:string}
type Type2 = {b:int}
При получении неизвестной строки я пытаюсь получить экземпляр правильного типа записи:
// Contents of a string might be like (1) or like (2), but we don't know which one
let someJsonString = "..."
let obj = JsonConvert.DeserializeObject(someJsonString)
Последняя строка возвращает объект типа Object.
Использование сопоставления с образцом на нем не определяет тип:
match obj with
| :? Type1 as t1 -> printfn "Type1: a = %A" t1.a
| :? Type2 as t2 -> printfn "Type2: b = %A" t2.b
| _ -> printfn "None of above"
Здесь «Ни один из выше» не печатается.
Когда я десериализация объекта с помощью индикации определенного типа:
JsonConvert.DeserializeObject<Type1>(someJsonString)
соответствия шаблона работает и печать:
Type1: a = <the value of a>
Однако, это не работает в моем случае, потому что я могу» t заранее знать, какой тип содержимого неизвестен для строки JSON.
Есть ли способ десериализации строки JSON в правильный тип записи на основе содержимого строки?
Примечание: При необходимости, когда строка сериализуется на стороне, на которой она отправляется, имя типа может быть отправлено как часть этой строки. Но тогда, как получить экземпляр типа Type, имеющий имя типа, типа «Type1» или «Type2»?
Полностью квалифицированное имя типа будет отличаться на разных машинах, поэтому я не уверен, что это возможно. То есть одна машина будет Type1 определен как:
"FSI_0059+Test1, FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
И еще один, как:
"FSI_0047+Test1, FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
Это не будет работать, если объект сериализации на одной машине, и десериализации на другой.Например, я пробовал это на одной машине - он может десериализовать объект на правильный тип. Но если вы десериализуете его на другой машине, полное имя типа отличается от типа, потому что оно имеет префикс с различными вариантами «FSI_0047 + Type1», например. Вы знаете, как убедиться, что у одного и того же типа есть одно и то же полное имя сборки для каждого запуска? – experimenter
Это потому, что вы используете FSI. Создаются имена. В противном случае разделите сборку между двумя машинами и укажите ее с помощью '# r'. – Asti
Спасибо, я думаю, это сработает – experimenter