Как я могу сериализовать кортежи как список в F #?

У меня есть библиотека, которая отправляет мне результаты, которые включают в себя кортежи. Мне нужно обработать некоторые данные, сериализовать их, а затем они отправляются в другую систему.

кортежи ВСЕГДА состоят из двух значений, но они очень расточительны при сериализации:

(3, 4)

будет сериализоваться как:

{"Item1":3,"Item2":4}

в то время как

[3; 4]

будет сериализоваться как:

[3,4]

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

Есть ли способ на уровне сериализатора преобразовать кортежи в список?

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

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

Всего 1 ответ


Вы можете переопределить поведение сериализации по умолчанию, указав свой собственный JsonConverter . В следующем примере показан модуль форматирования, который записывает кортежи int * int виде двухэлементных массивов JSON.

open Newtonsoft.Json

type IntIntConverter() = 
  inherit JsonConverter<int * int>()
  override x.WriteJson(writer:JsonWriter, (a:int,b:int), serializer:JsonSerializer) =
    writer.WriteStartArray()
    writer.WriteValue(a)
    writer.WriteValue(b)
    writer.WriteEndArray()

  override x.ReadJson(reader, objectType, existingValue, hasExistingValue, serializer) = 
    (0, 0)

let sample = [ (1,2); (3,4) ]
let json = JsonConvert.SerializeObject(sample, Formatting.None, IntIntConverter())

Результат выполнения этого будет [[1,2],[3,4]] . Обратите внимание, что я не реализовал метод ReadJson , поэтому вы еще не можете разобрать кортежи. Это потребует дополнительной работы, но вы можете посмотреть на существующие JsonConverter чтобы увидеть, как это сделать.

Также обратите внимание, что это для определенного типа кортежа, содержащего два целых числа. Если вам нужно поддерживать другие кортежи, вам, вероятно, потребуется предоставить несколько вариантов конвертера.


Есть идеи?

10000