Создание пользовательского сериализуемого типа значения

#c# #.net #.net-core

#c# #.net #.net-ядро

Вопрос:

Я пытаюсь создать пользовательский объект struct/class , который сериализуется в строку вместо объекта. Так, например.

 [Serializable]
struct MySerializableStringType : ISerializable
{
   public string _myProp

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("myprop", _myProp,  typeof(string));
        }

        public MySerializableStringType(SerializationInfo info, StreamingContext context)
        {
            _myProp= (string) info.GetValue("myprop", typeof(string));
        }

}
  

Эта приведенная выше реализация дает мне { "myprop" : "myvalue" } . Я хочу настроить приведенный выше код так, чтобы при сериализации он просто выдавал строку "myvalue" . Можно ли это сделать?

По сути, если бы у меня был другой объект

 class AnotherClass
{
 MySerializableStringType  myString;
 string systemString;
}
  

этот класс должен сериализоваться как
{ 'myString': 'value', 'systemString':'value'}

Примечание. Я не ищу пользовательское решение на основе JsonSerializer. Я хочу, чтобы он обрабатывался исключительно на уровне объекта c #.

Комментарии:

1. Но Serializable в первую очередь не сериализуется в JSON. Если у вас есть пользовательский код, который может взять Serializable объект и превратить его в JSON, это то, что нужно исследовать. Serializable не диктует формат on-the-wire, но в первую очередь предназначен для использования с двоичной сериализацией, и там тип (класс) является неотъемлемой частью вещей — если вы сериализуете в a string , он также будет десериализован как один. Возможный альтернативный подход заключается в том, чтобы предоставить вашему классу пользовательские операторы преобразования в / из string и использовать DTO для сериализации.

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

3. @Gusman смеется. тогда хорошо.

Ответ №1:

Сериализация также означает, что десериализация будет выполнена позже. Но то, что вы хотите, — это поездка в один конец. Если вы удалите имена полей, как вы могли бы безопасно десериализовать? В качестве решения только для сериализации я бы предложил переопределить метод toString .

Комментарии:

1. Система. Дата и время сериализуются в строку. И также возвращается к дате и времени. Нет?

2. @CodeReaper: на самом деле это зависит от используемой сериализации. Для двоичной сериализации («обычного» варианта использования Serializable ) ответом будет однозначное «нет» . Вы, конечно, можете сериализовать / десериализовать тип string любым удобным вам способом, но только до тех пор, пока механизм сериализации предлагает для этого опцию.

3. @CodeReaper: для синтаксического анализа строки с указанием даты или другого типа требуется знание формата. т.Е. 12.1.xxxx может быть 12 января или 1 декабря в зависимости от используемой вами культуры. Вот почему во многих языках программирования это называется синтаксическим анализом, а не десериализацией. Хорошая сериализация должна быть самоочевидной.

4. @haltunbay именно поэтому у нас есть стандарты, такие как ISO 8601

5. @JeroenMostert В качестве примера, System. Дата и время сериализуются Newtonsoft, где было добавлено пользовательское правило? Добавила ли Microsoft пользовательский сериализатор для Newtonsoft, который: «эй, Newtonsoft, используй это для нашего DateTime». AFAIK, я не видел этого атрибута в DateTime. ИЛИ , newtonsoft обработал это со своей стороны, что «всякий раз, когда мы получаем DataTime, в качестве исключения мы сериализуем его как строку». Опять же, как он может даже определить, что его дата-время?