Что такое [Сериализуемый] и когда я должен его использовать?

317

Я обнаружил, что некоторые классы используют этот [Serializable]атрибут.

  • Что это?
  • Когда я должен использовать это?
  • Какие преимущества я получу?
Кевин
источник
1
Вот практическое объяснение использования, которое я нашел.
Нипуна

Ответы:

368

Что это?

Когда вы создаете объект в приложении .Net Framework, вам не нужно думать о том, как данные хранятся в памяти. Потому что .Net Framework позаботится об этом за вас. Однако, если вы хотите сохранить содержимое объекта в файл, отправить объект другому процессу или передать его по сети, вам нужно подумать о том, как представлен объект, потому что вам нужно будет преобразовать его в другой формат. , Это преобразование называется СЕРИАЛИЗАЦИЯ.

Использует для сериализации

Сериализация позволяет разработчику сохранять состояние объекта и воссоздавать его по мере необходимости, обеспечивая хранение объектов, а также обмен данными. Посредством сериализации разработчик может выполнять такие действия, как отправка объекта в удаленное приложение с помощью веб-службы, передача объекта из одного домена в другой, передача объекта через брандмауэр в виде строки XML или поддержание безопасности или пользовательского уровня. информация между приложениями.

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

Все открытые и закрытые поля в типе, помеченные SerializableAttributeсимволом, сериализуются по умолчанию, если только тип не реализует ISerializableинтерфейс для переопределения процесса сериализации. Процесс сериализации по умолчанию исключает поля, отмеченные значком NonSerializedAttribute. Если поле сериализуемого типа содержит указатель, дескриптор или некоторую другую структуру данных, которая специфична для конкретной среды и не может быть разумно восстановлена ​​в другой среде, тогда вы можете применить NonSerializedAttributeк этому полю.

Смотрите MSDN для более подробной информации.

Редактировать 1

Любая причина не помечать что-то как сериализуемый

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

CharithJ
источник
1
@dwbartz На ваш вопрос ответили здесь ссылка
jayasurya_j
2
Хорошее объяснение, было бы неплохо добавить это к атрибуту в MSDN =)
Martea
@jayasurya_j Жаль, что принятый ответ мало говорит о закрытых частях
Александр
1
Хорошее объяснение
Закир ХК
42

Некоторые практические применения для [Serializable]атрибута:

  • Сохранение состояния объекта с помощью двоичной сериализации; вы можете очень легко «сохранить» все экземпляры объектов в вашем приложении в файле или сетевом потоке, а затем воссоздать их путем десериализации - проверьте BinaryFormatterкласс в System.Runtime.Serialization.Formatters.Binary
  • Написание классов, чьи экземпляры объектов могут храниться в буфере обмена с использованием Clipboard.SetData()- несериализуемые классы не могут быть помещены в буфер обмена.
  • Написание классов, совместимых с .NET Remoting; как правило, любой экземпляр класса, который вы передаете между доменами приложения (кроме тех, которые выходят из него MarshalByRefObject), должен быть сериализуемым.

Это наиболее распространенные случаи использования, с которыми я сталкивался.

Брэдли Смит
источник
42

Поскольку первоначальный вопрос касался атрибута SerializableAttribute, следует отметить, что этот атрибут применяется только при использовании BinaryFormatter или SoapFormatter.

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

Это НИЧЕГО не связано с сериализацией XML или JSON.

С SerializableAttribute используются интерфейс ISerializable и класс SerializationInfo. Они также используются только с BinaryFormatter или SoapFormatter.

Если вы не собираетесь сериализовать свой класс с использованием Binary или Soap, не пытайтесь пометить свой класс как [Serializable]. Сериализаторы XML и JSON даже не знают о его существовании.

BLaminack
источник
16
«Это не имеет никакого отношения к сериализации XML или JSON» - СПАСИБО! Наконец, объяснение, почему я могу с удовольствием сериализовать любой класс в XML с этим атрибутом или без него
userSteve
1
У вас есть источник для этого?
Мишель ван
«Сериализаторы XML и JSON даже не знают о его существовании». Я не знаю об этом. Когда я JSON отформатировал класс через WCF, имена свойств вышли с предшествующим подчеркиванием, если класс был Serializable, и без, когда атрибут был удален. Так что некоторые помехи возможны.
Дженс
@ Jens, если я правильно понял, JSON.net не заботится об этом, но asp.net немного меняет это поведение. Я считаю, что вы можете обойти это с помощью атрибутов JsonObject / JsonProperty.
База
29

Сериализация - это процесс преобразования объекта в поток байтов, чтобы сохранить объект или передать его в память, базу данных или файл.

Как работает сериализация

На этом рисунке показан общий процесс сериализации.

введите описание изображения здесь

Объект сериализуется в поток, который переносит не только данные, но и информацию о типе объекта, например его версию, культуру и имя сборки. Из этого потока он может быть сохранен в базе данных, файле или памяти.

Подробности в MSDN.

Махбубур Рахман
источник
19

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

Пример программы, объясняющей сериализацию

Если вы не понимаете вышеуказанную программу гораздо простая программа , с объяснением дается здесь .

Акшай
источник
14

Сериализация

Сериализация - это процесс преобразования графа объекта или набора объектов в поток, это массив байтов в случае двоичной сериализации

Использование Сериализации

  1. Чтобы сохранить состояние объекта в файл, базу данных и т. Д. И использовать его последним.
  2. Чтобы отправить объект из одного процесса в другой (домен приложения) на том же компьютере, а также отправить его по проводам процессу, запущенному на другом компьютере.
  3. Создать клон исходного объекта в качестве резервной копии при работе с основным объектом.
  4. Набор объектов может быть легко скопирован в буфер обмена системы, а затем вставлен в то же или другое приложение

Ниже приведены некоторые полезные пользовательские атрибуты, которые используются во время сериализации объекта.

[Serializable] -> Используется, когда мы помечаем сериализуемый объект [NonSerialized] -> Используется, когда мы не хотим сериализовать поле объекта. [OnSerializing] -> Используется, когда мы хотим выполнить какое-либо действие при сериализации объекта. [OnSerialized] -> Используется, когда мы хотим выполнить какое-либо действие после сериализации объекта в поток.

Ниже приведен пример сериализации

[Serializable]
    internal class DemoForSerializable
    {
        internal string Fname = string.Empty;
        internal string Lname = string.Empty;

        internal Stream SerializeToMS(DemoForSerializable demo)
        {
            DemoForSerializable objSer = new DemoForSerializable();
            MemoryStream ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, objSer);
            return ms;
        }

        [OnSerializing]
        private void OnSerializing(StreamingContext context) {
            Fname = "sheo";
            Lname = "Dayal";
        }
        [OnSerialized]
        private void OnSerialized(StreamingContext context)
        {
       // Do some work after serialized object
        }

    }

Вот код вызова

class Program
    {
        string fname = string.Empty;
        string Lname = string.Empty; 

       static void Main(string[] args)
        {
            DemoForSerializable demo = new DemoForSerializable();

            Stream ms = demo.SerializeToMS(demo);
            ms.Position = 0;

            DemoForSerializable demo1 = new BinaryFormatter().Deserialize(ms) as DemoForSerializable;

            Console.WriteLine(demo1.Fname);
            Console.WriteLine(demo1.Lname);
            Console.ReadLine();
        }

    }
Шео Дайал Сингх
источник