Яка різниця між використанням атрибута Serializable та реалізацією ISerializable?


Відповіді:


41

Коли ви використовуєте SerializableAttributeатрибут, ви розміщуєте атрибут у полі під час компіляції таким чином, що під час виконання, засоби серіалізації знатимуть, що серіалізувати на основі атрибутів, виконуючи роздуми про клас / модуль / збірку типу.

[Serializable]
public class MyFoo { … }

Вищезазначене вказує на те, що засіб серіалізації має серіалізувати весь клас MyFoo, тоді як:

public class MyFoo
{
    private int bar;

    [Serializable]
    public int WhatBar
    {
       get { return this.bar; }
    }
}

Використовуючи атрибут, ви можете вибірково вибрати, які поля потрібно серіалізувати.

Коли ви реалізуєте ISerializableінтерфейс , серіалізація фактично замінюється на користувацьку версію, замінюючи і (і надаючи конструктор форми ), буде вищий ступінь контролю над серіалізацією даних.GetObjectData SetObjectDataMyFoo(SerializationInfo info, StreamingContext context)

Дивіться також цей приклад користувацької серіалізації тут, на StackOverflow . Він показує, як зберегти серіалізацію зворотньо сумісною з різними версіями серіалізованих даних.

Сподіваюся, це допомагає.


11
У якій версії .NET нормально додавати Serializableатрибут до властивості? MSDN каже, що його можна застосовувати лише до класів, структур, переліків та делегатів.
повішений

5
Жоден. Атрибут, який можна серіалізувати, не можна застосовувати до властивостей, лише до оголошень класу, структури та переліку та делегатів.
Даніель Лейзен

3
Все навпаки: коли клас прикрашений SerializableAttribute, член може бути позначений, NonSerializedAttributeщоб його пропустити, як сказали багато людей (і MSDN), коли реконструкція певного об’єкта безглузда в іншому середовищі, розумно не проводити його серіалізацію. ..
nurchi

20

SerializableAttribute інструктує рамки , щоб зробити процес серіалізациі за замовчуванням. Якщо вам потрібен додатковий контроль, ви можете застосувати інтерфейс ISerializable . Потім ви б розмістили власний код для серіалізації об’єкта в GetObjectDataметоді та оновлення SerializationInfoоб’єкта, який йому передано.


4
Якщо ви впроваджуєте ISerializable, також прийнято (або, можливо, навіть потрібно) реалізовувати конструктор десериалізації: захищений SomeClass (інформація про SerializationInfo, контекст StreamingContext)
jrista

18
Зверніть увагу, що ви все одно повинні позначити клас [Серіалізувальний], навіть якщо ви реалізуєте інтерфейс ISerializable.
Адам Лір

3

ISerializableІнтерфейс дозволяє реалізувати власні сериализации , крім по замовчуванням. Коли ви реалізуєте ISerializableінтерфейс, вам доведеться перевизначити GetObjectDataметод наступним чином

public void GetObjectData (SerializationInfo serInfo, 
                                    StreamingContext streamContext)
{
   // Implement custom Serialization
}

1

ISerialize змушує вас реалізовувати логіку серіалізації маніально, тоді як позначення за допомогою атрибута Serializable (ви це мали на увазі?) Скаже Binary serializer, що цей клас можна серіалізувати. Він зробить це автоматично.


0

Успадкування від ISerializable дозволяє спеціально реалізувати (де) серіалізацію. Використовуючи лише атрибут Serializable, (де) серіалізація може контролюватися лише атрибутами і є менш гнучкою.


Десериалізація обробляється за допомогою конструктора десеріалізації. Дивіться мій коментар щодо відповідей segfaults.
jrista
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.