[Serializable] คืออะไรและเมื่อใดที่ฉันควรใช้


317

ฉันพบว่าบางคลาสใช้[Serializable]คุณสมบัติ

  • มันคืออะไร?
  • ฉันควรใช้เมื่อใด
  • ฉันจะได้รับประโยชน์อะไรบ้าง



1
นี่คือคำอธิบายการใช้งานจริงที่ฉันพบ
Nipuna

คำตอบ:


368

มันคืออะไร?

เมื่อคุณสร้างวัตถุในแอปพลิเคชัน. Net Framework คุณไม่จำเป็นต้องคิดเกี่ยวกับวิธีการจัดเก็บข้อมูลในหน่วยความจำ เพราะ. Net Framework จะดูแลสิ่งนั้นให้คุณ อย่างไรก็ตามหากคุณต้องการจัดเก็บเนื้อหาของวัตถุไปยังไฟล์ส่งวัตถุไปยังกระบวนการอื่นหรือส่งผ่านเครือข่ายคุณต้องคิดเกี่ยวกับวิธีการแสดงวัตถุเนื่องจากคุณจะต้องแปลงเป็นรูปแบบอื่น . การแปลงนี้เรียกว่า SERIALIZATION

ใช้สำหรับการทำให้เป็นอันดับ

การทำให้เป็นอนุกรมช่วยให้นักพัฒนาสามารถบันทึกสถานะของวัตถุและสร้างใหม่ได้ตามต้องการจัดเก็บข้อมูลของวัตถุและแลกเปลี่ยนข้อมูล ผู้พัฒนาสามารถดำเนินการต่าง ๆ เช่นการส่งวัตถุไปยังแอปพลิเคชันระยะไกลโดยใช้บริการเว็บผ่านวัตถุจากโดเมนหนึ่งไปยังอีกโดเมนหนึ่งผ่านวัตถุผ่านไฟร์วอลล์เป็นสตริง XML หรือรักษาความปลอดภัยหรือเฉพาะผู้ใช้ ข้อมูลข้ามแอปพลิเคชัน

นำSerializableAttributeไปใช้กับประเภทเพื่อระบุว่าอินสแตนซ์ของประเภทนี้สามารถต่อเนื่องกันได้ ใช้SerializableAttributeคลาสถึงแม้ว่าจะใช้ISerializableอินเทอร์เฟซเพื่อควบคุมกระบวนการทำให้เป็นอนุกรม

ฟิลด์สาธารณะและส่วนตัวทั้งหมดในประเภทที่มีการทำเครื่องหมายโดยSerializableAttributeจะต่อเนื่องกันเป็นค่าเริ่มต้นเว้นแต่ประเภทที่ดำเนินการISerializableอินเตอร์เฟซที่จะแทนที่กระบวนการอนุกรม NonSerializedAttributeเขตข้อมูลที่ไม่รวมขั้นตอนการเริ่มต้นเป็นอันดับที่มีเครื่องหมาย หากเขตข้อมูลชนิดที่ต่อเนื่องกันได้มีตัวชี้หมายเลขอ้างอิงหรือโครงสร้างข้อมูลอื่น ๆ ที่เฉพาะเจาะจงกับสภาพแวดล้อมเฉพาะและไม่สามารถสร้างขึ้นใหม่อย่างมีความหมายในสภาพแวดล้อมที่แตกต่างกันคุณอาจต้องการนำNonSerializedAttributeไปใช้กับเขตข้อมูลนั้น

ดูMSDNสำหรับรายละเอียดเพิ่มเติม

แก้ไข 1

เหตุผลใด ๆ ที่จะไม่ทำเครื่องหมายสิ่งที่เป็นอนุกรม

เมื่อโอนหรือบันทึกข้อมูลคุณต้องส่งหรือบันทึกเฉพาะข้อมูลที่ต้องการ ดังนั้นจะมีความล่าช้าในการถ่ายโอนและปัญหาการเก็บข้อมูลน้อยลง ดังนั้นคุณสามารถยกเลิกการรับรู้ข้อมูลที่ไม่จำเป็นเมื่อทำการจัดลำดับ


1
@dwbartz คำถามของคุณเป็นคำตอบที่นี่ เชื่อมโยง
jayasurya_j

2
การอธิบายที่ดีจะเป็นการดีที่จะเพิ่มสิ่งนี้ลงในแอตทริบิวต์ใน MSDN =)
Martea

@jayasurya_j เลวร้ายเกินไปคำตอบที่ได้รับการยอมรับไม่ได้พูดถึงชิ้นส่วนส่วนตัว
Alexander

1
คำอธิบายที่ดี
Zakir HC

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 serializers ไม่ได้ตระหนักถึงการมีอยู่ของมัน


16
"มันไม่มีอะไรเกี่ยวข้องกับ XML หรือการทำให้เป็นอันดับ JSON" - ขอขอบคุณ! ในที่สุดคำอธิบายว่าทำไมฉันจึงสามารถทำให้คลาสใด ๆ เป็น XML อย่างมีความสุขโดยมีหรือไม่มีแอตทริบิวต์นี้
userSteve

1
คุณมีแหล่งที่มาสำหรับสิ่งนี้หรือไม่?
Michiel van Oosterhout

"XML และ JSON serializers ไม่ได้ตระหนักถึงการมีอยู่ของมัน" ฉันไม่รู้เรื่องนั้น เมื่อฉัน JSON จัดรูปแบบคลาสผ่าน WCF ชื่อคุณสมบัติจะออกมาพร้อมกับขีดล่างก่อนหน้าถ้าคลาสนั้นอยู่Serializableและไม่มีเมื่อแอตทริบิวต์ถูกลบออก ดังนั้นการรบกวนบางอย่างเป็นไปได้
เจนส์

@Jens ถ้าฉันเข้าใจถูกต้อง JSON.net ไม่สนใจเรื่องนี้ แต่ asp.net เปลี่ยนพฤติกรรมนี้เล็กน้อย ฉันเชื่อว่าคุณสามารถหลีกเลี่ยงสิ่งนี้ได้ด้วยคุณสมบัติ JsonObject / JsonProperty
ฐาน

29

การทำให้เป็นอันดับเป็นกระบวนการของการแปลงวัตถุเป็นกระแสข้อมูลไบต์เพื่อเก็บวัตถุหรือส่งไปยังหน่วยความจำฐานข้อมูลหรือไฟล์

วิธีการทำให้เป็นอันดับ

ภาพประกอบนี้แสดงกระบวนการโดยรวมของการทำให้เป็นอนุกรม

ป้อนคำอธิบายรูปภาพที่นี่

วัตถุนั้นได้รับการต่อเนื่องเป็นกระแสซึ่งไม่เพียง แต่นำเสนอข้อมูล แต่เป็นข้อมูลเกี่ยวกับประเภทของวัตถุเช่นรุ่นวัฒนธรรมและชื่อแอสเซมบลี จากสตรีมนั้นสามารถเก็บไว้ในฐานข้อมูลไฟล์หรือหน่วยความจำ

รายละเอียดเป็น msdn


19

นี่คือตัวอย่างสั้น ๆ เกี่ยวกับการทำงานของการทำให้เป็นอันดับ ฉันยังได้เรียนรู้เกี่ยวกับสิ่งเดียวกันและฉันพบว่าลิงก์ทั้งสองมีประโยชน์ อะไรเป็นอันดับและวิธีการที่สามารถทำได้ใน .NET

โปรแกรมตัวอย่างอธิบายการทำให้เป็นอนุกรม

ถ้าคุณไม่เข้าใจโปรแกรมดังกล่าวข้างต้นเป็นโปรแกรมที่ง่ายมากที่มีคำอธิบายจะได้รับที่นี่


14

การทำให้เป็นอันดับ

การทำให้เป็นอันดับเป็นกระบวนการของการแปลงวัตถุหรือชุดของกราฟวัตถุเป็นกระแสมันเป็นอาร์เรย์ไบต์ในกรณีของการเป็นอนุกรมไบนารี

การใช้งานของการทำให้เป็นอันดับ

  1. เพื่อบันทึกสถานะของวัตถุลงในไฟล์ฐานข้อมูล ฯลฯ และใช้มันในภายหลัง
  2. ในการส่งวัตถุจากกระบวนการหนึ่งไปยังอีกกระบวนการหนึ่ง (App Domain) บนเครื่องเดียวกันและส่งผ่านสายไปยังกระบวนการที่ทำงานบนเครื่องอื่น
  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();
        }

    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.