Co to jest [Serializable] i kiedy powinienem go używać?

Odpowiedzi:

369

Co to jest?

Podczas tworzenia obiektu w aplikacji .NET Framework nie musisz myśleć o tym, jak dane są przechowywane w pamięci. Ponieważ .Net Framework dba o to za Ciebie. Jeśli jednak chcesz zapisać zawartość obiektu do pliku, wysłać obiekt do innego procesu lub przesłać go przez sieć, musisz pomyśleć o tym, jak obiekt jest reprezentowany, ponieważ będziesz musiał przekonwertować go na inny format . Ta konwersja nosi nazwę SERIALIZATION.

Zastosowania do serializacji

Serializacja pozwala deweloperowi zapisać stan obiektu i odtworzyć go w razie potrzeby, zapewniając przechowywanie obiektów oraz wymianę danych. Dzięki serializacji deweloper może wykonywać takie czynności, jak wysyłanie obiektu do aplikacji zdalnej za pomocą usługi sieci Web, przekazywanie obiektu z jednej domeny do drugiej, przekazywanie obiektu przez zaporę jako ciąg XML lub utrzymywanie zabezpieczeń lub specyficznych dla użytkownika informacje między aplikacjami.

Zastosuj SerializableAttributedo typu, aby wskazać, że instancje tego typu mogą być serializowane. Zastosuj, SerializableAttributenawet jeśli klasa implementuje również ISerializableinterfejs do sterowania procesem serializacji.

Wszystkie pola publiczne i prywatne w typie oznaczonym przez SerializableAttributesą domyślnie serializowane, chyba że typ implementuje ISerializableinterfejs w celu zastąpienia procesu serializacji. Domyślny proces serializacji wyklucza pola oznaczone NonSerializedAttribute. Jeśli pole typu możliwego do serializacji zawiera wskaźnik, uchwyt lub inną strukturę danych, która jest specyficzna dla określonego środowiska i nie może być znacząco odtworzona w innym środowisku, możesz zastosować NonSerializedAttributeto pole.

Aby uzyskać więcej informacji, zobacz MSDN .

Edytuj 1

Każdy powód, aby nie oznaczać czegoś jako możliwego do serializacji

Podczas przesyłania lub zapisywania danych musisz wysłać lub zapisać tylko wymagane dane. Dzięki temu będzie mniej opóźnień transferu i problemów z pamięcią. Możesz więc zrezygnować z niepotrzebnego fragmentu danych podczas serializacji.

CharithJ
źródło
1
@dwbartz Odpowiedzi na twoje pytanie tutaj link
jayasurya_j
2
Fajne wyjaśnienie, fajnie byłoby dodać to do atrybutu w MSDN =)
Martea
@jayasurya_j Szkoda, że ​​zaakceptowana odpowiedź nie mówi wiele o częściach prywatnych
Alexander
1
Dobre wyjaśnienie
Zakir HC
42

Kilka praktycznych zastosowań tego [Serializable]atrybutu:

  • Zapisywanie stanu obiektu przy użyciu serializacji binarnej; możesz bardzo łatwo „zapisać” instancje całego obiektu w aplikacji do strumienia pliku lub sieci, a następnie odtworzyć je przez deserializację - sprawdź BinaryFormatterklasę w System.Runtime.Serialization.Formatters.Binary
  • Pisanie klas, których instancje obiektowe mogą być przechowywane w schowku przy użyciu Clipboard.SetData()- nie można umieszczać w schowku klas, których nie można wydzielić.
  • Pisanie klas kompatybilnych z .NET Remoting; generalnie każda instancja klasy przekazywana między domenami aplikacji (oprócz tych, które rozciągają się od MarshalByRefObject) musi być możliwa do serializacji.

Są to najczęstsze przypadki użycia, z którymi się spotkałem.

Bradley Smith
źródło
41

Ponieważ oryginalne pytanie dotyczyło SerializableAttribute, należy zauważyć, że ten atrybut ma zastosowanie tylko w przypadku korzystania z BinaryFormatter lub SoapFormatter.

Jest to trochę mylące, chyba że naprawdę zwracasz uwagę na szczegóły, co do tego, kiedy go użyć i jaki jest jego rzeczywisty cel.

Nie ma to nic wspólnego z serializacją XML lub JSON.

Wraz z SerializableAttribute stosuje się interfejs ISerializable i klasę SerializationInfo. Są one również używane tylko z BinaryFormatter lub SoapFormatter.

O ile nie zamierzasz serializować swojej klasy za pomocą Binarnego lub Mydła, nie zawracaj sobie głowy oznaczaniem swojej klasy jako [Serializable]. Serializatory XML i JSON nawet nie są świadome jego istnienia.

BLaminack
źródło
16
„Nie ma to nic wspólnego z serializacją XML lub JSON” - DZIĘKUJĘ! Wreszcie wyjaśnienie, dlaczego z radością mogę serializować dowolną klasę do
formatu
1
Czy masz na to źródło?
Michiel van Oosterhout
„Serializatory XML i JSON nawet nie są świadome jego istnienia”. Nie wiem o tym Kiedy I JSON sformatował klasę za pomocą WCF, nazwy właściwości pojawiły się z poprzedzającym podkreśleniem, jeśli klasa była Serializable, i bez, gdy atrybut został usunięty. Tak więc możliwe są pewne zakłócenia.
Jens
@Jens, jeśli dobrze zrozumiałem JSON.net, nie obchodzi mnie to trochę, ale asp.net nieco to zmienia. Wierzę, że można to obejść za pomocą atrybutów JsonObject / JsonProperty.
Baza
29

Serializacja to proces przekształcania obiektu w strumień bajtów w celu przechowywania obiektu lub przesłania go do pamięci, bazy danych lub pliku.

Jak działa serializacja?

Ta ilustracja pokazuje ogólny proces serializacji.

wprowadź opis zdjęcia tutaj

Obiekt jest serializowany do strumienia, który przenosi nie tylko dane, ale informacje o typie obiektu, takie jak jego wersja, kultura i nazwa zestawu. Z tego strumienia można go przechowywać w bazie danych, pliku lub pamięci.

Szczegóły w msdn.

Mahbubur Rahman
źródło
14

Serializacja

Serializacja to proces przekształcania wykresu obiektu lub zestawu obiektów w strumień, w przypadku serializacji binarnej jest to tablica bajtów

Zastosowania serializacji

  1. Aby zapisać stan obiektu w pliku, bazie danych itp. I użyć go później.
  2. Aby wysłać obiekt z jednego procesu do drugiego (Domena aplikacji) na tym samym komputerze, a także przesłać go przewodowo do procesu działającego na innym komputerze.
  3. Aby utworzyć klon oryginalnego obiektu jako kopię zapasową podczas pracy nad głównym obiektem.
  4. Zestaw obiektów można łatwo skopiować do schowka systemu, a następnie wkleić do tej samej lub innej aplikacji

Poniżej znajduje się kilka przydatnych niestandardowych atrybutów używanych podczas serializacji obiektu

[Serializable] -> Jest używany, gdy zaznaczamy obiekt do serializacji [NonSerialized] -> Jest używany, gdy nie chcemy serializować pola obiektu. [OnSerializing] -> Jest używany, gdy chcemy wykonać jakąś akcję podczas serializacji obiektu [OnSerialized] -> Jest używany, gdy chcemy wykonać jakąś akcję po serializacji obiektu do strumienia.

Poniżej znajduje się przykład serializacji

[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
        }

    }

Oto kod wywołujący

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();
        }

    }
Sheo Dayal Singh
źródło