У меня есть дерево объектов, которое я сериализую в JSON с DataContractJsonSerializer
.Dictionary<TKey, TValue>
сериализуется, но мне не нравится разметка - элементы отображаются не так:
{key1:value, key2:value2}
, а скорее как массив сериализованных KeyValuePair<TKey, TValue>
объектов:
[{
"__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
"key":"key1",
"value":"value1"
},
{
"__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
"key":"key2",
"value":"value2"
}]
Ужасно, не правда ли?
Итак, я избегаю этого, оборачивая универсальный словарь в пользовательский объект, который реализует ISerializable
, и я реализую свою собственную сериализацию в методе GetObjectData
(и этозанимает всего 3 строки).
Теперь проблема - я не могу сделать мой класс производным от Dictionary<TKey, TValue>
, поэтому я реализую всю логику (Add
, Clear
и т. д.) в своем пользовательском классе, применяется к частному Dictionary<TKey, TValue>
полю.Наследование было бы предпочтительным, так как при использовании моего пользовательского объекта в моем распоряжении будут все общие функции словаря.
Проблема с наследованием заключается в том, что Dictionary<TKey, TValue>
реализует ISerializable
самостоятельно, а DataContractJsonSerializer
кажетсяЯ предпочитаю эту реализацию, даже если я реализую ISerializable
явно из своего пользовательского класса, например:
public class MyClass : Dictionary<string, object>, ISerializable
{
public override void GetObjectData(SerializationInfo info,
StreamingContext context)
}
Я был на самом деле удивлен, что это возможно, так как это позволяет мне реализовать один и тот же интерфейс дважды, не будучи явновозможность использовать явную реализацию интерфейса - поэтому я проанализировал ситуацию более подробно в блоге о реализации нескольких интерфейсов
Итак, в соответствии с проведенными мною экспериментами сериализатор должен вызыватьмоя реализация ISerializable, независимо от того, какой тип приведения используется внутренне -
((ISerializable)((Dictionary<,>)obj)).GetObjectData(...)
или:
((ISerializable)obj).GetObjectData(...)
, но, очевидно, этого не происходит, как я вижу в полученном JSON,сериализатор KeyValuePair<TKey, TValue>
все еще вызывается.Что может случиться, что я пропускаю?
Обновление: ответы и комментарии, которые я получаю до сих пор, в значительной степени только предлагают обходные пути.Однако я отметил, что у меня есть обходной путь, который работает довольно хорошо, поэтому, задавая этот вопрос, я ставлю перед собой две цели:
В конечном итоге заставить его работать с оригинальным дизайном - и я неЯ собираюсь изменить логику сериализации только для этого, от нее зависит много кода и логики
Чтобы понять загадку, почему DataContractJsonSerializer
не использует мой код сериализации -Как видно из сообщения в блоге, на которое я ссылался, я проводил всевозможные эксперименты с реализацией и наследованием интерфейса, и я был уверен, что понимаю все тонкости этого процесса, поэтому меня беспокоят непониманиечто происходит в этом случае