C# [serializable] jelentése

Címkék
C# [serializable] jelentése
2021-04-09T19:39:48+02:00
2021-04-10T20:18:00+02:00
2022-12-06T18:55:35+01:00
yguernen
Sziasztok!
Szeretném megérteni a címben írt formulát.
Egy könyv egyik példakódjában láttam ezt.
Egy osztály elé volt beszúrva. Annyit írt róla a könyv, hogy az adatok fájlban való tárolás miatt szükséges.
Az attribútomok használata mikor indokolt és miért szükséges?

Köszönöm.
Mutasd a teljes hozzászólást!
Induljunk ki onnan, hogy az objektumorientált programozásban van egy alapvető különbség az osztály és az objektum között. Bár azt tudjuk, hogy az objektum egy osztály egy példányát jelenti, de alapvető különbség, hogy állapota van. (Igen, tudom, hogy meg lehet erőszakolni az OOP-t és vannak static tulajdonságok is, ez most out-of-scope). Az állapot pedig azt jelenti, hogy az objektum tulajdonságainak egy adott pillanatban milyen értékei vannak.

Vegyük az alábbi kódot:

record Person { public string FirstName { get; init; } public string LastName { get; init; } } Person p1 = new Person { FirstName = "Edina", LastName = "Tóth" }; Person p2 = new Person { FirstName = "István", LastName = "Horváth" };
Az alábbi példában a p1 állapota az, hogy az emberünket Tóth Edinának, p2 esetében pedig Horváth Istvánnak hívják.

A szerializáció azt a nemes célt szolgálja, hogy az objektum állapotát valamilyen olyan adatfolyammá alakítjuk, amelyet I/O csatornán közvetíteni tudunk - vagyis el tudjuk menteni lemezre, hogy később visszatöltsük, át tudjuk egy másik alkalmazásnak küldeni hálózaton, hogy az a másik szoftver feldolgozza ezt az információt, stb. Szerializációnak hívjuk azt a folyamatot, amikor az objektum állapotából I/O-ra tehető adatfolyamot csinálunk. A deszerializáció pedig ennek az ellentéte, mely során példányosítjuk az osztályt és a létrejött objektumnak visszaállítjuk az állapotát a szerializált információkból. A szerializáció által előállt adat pedig platform- és nyelvfüggetlen, tehát ha szerializálsz egy C#-ban írt osztályt Windows-on, egy JavaScript-ben írt programnak (ami történetesen Linuxon fut) azt tudnia kell deszerializálni a saját objektum-reprezentációjára.

Szerializálni sok formátumba lehet. Csinálhatsz belőle binárisan kódolt adatot, JSON, XML, YAML és egyéb szöveges formátumot.

Ez a szerializáció azonban nem a világ legegyszerűbb dolga. A háttérben általában valamilyen reflection módszer működik (pont emiatt költséges is a folyamat), és hogy megkönnyítsék az életünket, erre a feladatra komplett szerializáló frameworkök jöttek létre. Van beépítve ilyen a .NET-ben, de léteznek third-party kódok is (Newtonsoft.JSON és a többiek). Microsofték kezdték el azt csinálni, hogy a framework csak akkor hajlandó szerializálni/deszerializálni, ha a SerializableAttribute-tal annotáltad az osztályt. Más frameworkök, mint a Newtonsoft.JSON nem támasztanak ilyen követelményeket.

Általában a legtöbb szerializáló framework olyan osztályokkal tud együttműködni, amelynek van public paraméter nélküli konstruktora. Ezt onnan tudod, hogy kivételt kapsz, ha deszerializálni szeretnél. Ez gond, ugyanis lekorlátozza a fejlesztő lehetőségeit, például nagyon nehézzé/lehetetlenné teszi az immutable osztályok szerializálását/deszerializálását. (Immutable osztály: Olyan osztály, amely példányainak az állapotát nem lehet megváltoztatni annak létrejötte után.) Ha egy framework ilyen megszorítást tesz a konstruktor alakjára, azt constrained constructor antipatternnek nevezzük (antipattern = kerülendő minta, ami megnehezíti az életedet). Egyes szerlializáló frameworkök nyújtanak erre megoldást, például a Newtonsoft.JSON együtt tud működni bármilyen konstruktorral, amíg megfelelően annotálva van az osztály és a konstruktor (valahonnan tudnia kell, hogy miképp lehet a konstruktort meghívni).

Több területe van a szoftverfejlesztésnek, ahol ezt a technikát alkalmazzák. Például majd ha RESTful API-t fogsz fejleszteni, tárolhatod így az alkalmazásod beállításait, stb.
Mutasd a teljes hozzászólást!

  • Szerializáció, amikor egy memória reprezentációt állomány reprezentációba alakítunk. Ami így fileben tárolható vagy átvihető másik gépre. Ennek fordítottja a deszerializálás.

    Ez az attributum egy jogosultság flag igazán, hogy jelezzük, ha engedjük, hogy az oesztálypéldányt szerializálni lehessen (potenciálisan nem biztonságos környezetbe exportálva a tartalmazott adatokat).

    Persze nem igazán értelmes mára, mert pl. JSon serializálás nem figyeli illetve bárki írhat saját szerializációt, amit nem érdekel az attributum megléte.
    Mutasd a teljes hozzászólást!
  • Azt jelenti, hogy az osztály egy adott példányát lehet csúnyán mondva fájlba menteni, valamint onnan betölteni. Mondjuk egy BinaryFormatter segítségével, hogy egy ősi megoldást hozzak. Hasznos tud lenni néha, mert nem kell manuálisan lementegetni a változókat és betölteni.

    Tehát nem az egyes változókat, hanem konkrétan azt az osztálypéldányt mented le és töltöd vissza.
    Mutasd a teljes hozzászólást!
  • Ezt az attribútumot csak a SoapFormatter meg a BinaryFormatter használja, előnye és egyben hátránya is, hogy a privát mezőket is elmenti/visszatölti fájlba.
    Általános célra inkább használj json szerializációt pl. a System.Text.Json névtérből. Ennek is vannak attribútumai, pl. egyes mezőket ki lehet hagyni a JsonIgnore attribútummal, de az osztályt nem kell megjelölni semmivel, hogy szerializálható legyen, mert minden is az.

    Szerializálás string-be

    var jsonString = JsonSerializer.Serialize(obj);
    Deszerializálás:

    var obj = JsonSerializer.Deserialize<Típus>(jsonString);
    Mutasd a teljes hozzászólást!
  • Induljunk ki onnan, hogy az objektumorientált programozásban van egy alapvető különbség az osztály és az objektum között. Bár azt tudjuk, hogy az objektum egy osztály egy példányát jelenti, de alapvető különbség, hogy állapota van. (Igen, tudom, hogy meg lehet erőszakolni az OOP-t és vannak static tulajdonságok is, ez most out-of-scope). Az állapot pedig azt jelenti, hogy az objektum tulajdonságainak egy adott pillanatban milyen értékei vannak.

    Vegyük az alábbi kódot:

    record Person { public string FirstName { get; init; } public string LastName { get; init; } } Person p1 = new Person { FirstName = "Edina", LastName = "Tóth" }; Person p2 = new Person { FirstName = "István", LastName = "Horváth" };
    Az alábbi példában a p1 állapota az, hogy az emberünket Tóth Edinának, p2 esetében pedig Horváth Istvánnak hívják.

    A szerializáció azt a nemes célt szolgálja, hogy az objektum állapotát valamilyen olyan adatfolyammá alakítjuk, amelyet I/O csatornán közvetíteni tudunk - vagyis el tudjuk menteni lemezre, hogy később visszatöltsük, át tudjuk egy másik alkalmazásnak küldeni hálózaton, hogy az a másik szoftver feldolgozza ezt az információt, stb. Szerializációnak hívjuk azt a folyamatot, amikor az objektum állapotából I/O-ra tehető adatfolyamot csinálunk. A deszerializáció pedig ennek az ellentéte, mely során példányosítjuk az osztályt és a létrejött objektumnak visszaállítjuk az állapotát a szerializált információkból. A szerializáció által előállt adat pedig platform- és nyelvfüggetlen, tehát ha szerializálsz egy C#-ban írt osztályt Windows-on, egy JavaScript-ben írt programnak (ami történetesen Linuxon fut) azt tudnia kell deszerializálni a saját objektum-reprezentációjára.

    Szerializálni sok formátumba lehet. Csinálhatsz belőle binárisan kódolt adatot, JSON, XML, YAML és egyéb szöveges formátumot.

    Ez a szerializáció azonban nem a világ legegyszerűbb dolga. A háttérben általában valamilyen reflection módszer működik (pont emiatt költséges is a folyamat), és hogy megkönnyítsék az életünket, erre a feladatra komplett szerializáló frameworkök jöttek létre. Van beépítve ilyen a .NET-ben, de léteznek third-party kódok is (Newtonsoft.JSON és a többiek). Microsofték kezdték el azt csinálni, hogy a framework csak akkor hajlandó szerializálni/deszerializálni, ha a SerializableAttribute-tal annotáltad az osztályt. Más frameworkök, mint a Newtonsoft.JSON nem támasztanak ilyen követelményeket.

    Általában a legtöbb szerializáló framework olyan osztályokkal tud együttműködni, amelynek van public paraméter nélküli konstruktora. Ezt onnan tudod, hogy kivételt kapsz, ha deszerializálni szeretnél. Ez gond, ugyanis lekorlátozza a fejlesztő lehetőségeit, például nagyon nehézzé/lehetetlenné teszi az immutable osztályok szerializálását/deszerializálását. (Immutable osztály: Olyan osztály, amely példányainak az állapotát nem lehet megváltoztatni annak létrejötte után.) Ha egy framework ilyen megszorítást tesz a konstruktor alakjára, azt constrained constructor antipatternnek nevezzük (antipattern = kerülendő minta, ami megnehezíti az életedet). Egyes szerlializáló frameworkök nyújtanak erre megoldást, például a Newtonsoft.JSON együtt tud működni bármilyen konstruktorral, amíg megfelelően annotálva van az osztály és a konstruktor (valahonnan tudnia kell, hogy miképp lehet a konstruktort meghívni).

    Több területe van a szoftverfejlesztésnek, ahol ezt a technikát alkalmazzák. Például majd ha RESTful API-t fogsz fejleszteni, tárolhatod így az alkalmazásod beállításait, stb.
    Mutasd a teljes hozzászólást!
  • Köszönöm a részletes magyarázatot.
    A többieknek is köszönöm a választ.
    Mutasd a teljes hozzászólást!
Címkék
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd