Binaryformatter serialization instance (5)

Source: Internet
Author: User

When voucher [] vouchers is serialized, we can see that the Assembly and type information is generated only once. However, if vouchers contains instances of classes derived from voucher, that is to say, when vouchers is a multi-state array, what is the situation. If binnaryformatter stores static data, the object cannot be completely restored during deserialization. On the other hand, because the parameters of the binaryformatter. serialize method are of the object type, binaryformatter should save the dynamic type of the object. To verify this conjecture, billvoucher is derived from the voucher class.

Billvoucher indicates the credential generated from the document. It needs to track the original document. The billvoucher class is defined as follows:

Namespace Generalledger

{

Public   Class Billvoucher: voucher

{

Private   String Billid;



Public Billvoucher ( String Billid, String Voucherid, String Creator, datetime createtime ): Base (Voucherid, creator, createtime)

{

This. Billid=Billid;

}


Public   String Billid

{

Get

{

ReturnBillid;

}

}

}

}

Note that billvoucher does not add serializableattribute because some attributes can be inherited from the base class. So can serializableattribute be inherited? Use nunit to add the Test method:

[Test]

Public   Void Testserializebillvoucher ()

{

Billvoucher voucher =   New Billvoucher ( " 2005020400001 " , " 2005012900001 " , " Xingd " , Datetime. Now );

Voucherserializer serializer =   New Voucherserializer ();

Serializer. serialize ( " Voucher. dat " , Voucher );

}

Run nunit to test and report an error. Will it be because the derived class has an additional field? Comments The billid temporarily and report the same error during the test. We can see that,Serializableattribute must be added to classes that support binaryformatter serialization. Even its base classes support binaryformatter serialization.After adding serializableattribute to billvoucher, the test passes.

What happens if the base class does not support serialization and the derived class has added serializableattribute? In actual application, it should not be allowed. Otherwise, it means that any class that can be derived can be indirectly serialized. For further verification, comment out the serializableattribute of the voucher class. Run nunit test testserializebillvoucher. The error message is as follows:

Generalledger. vouchertest. Failed: system. runtime. serialization. serializationexception: The type generalledger. Voucher in assembly voucher, version = enabled, culture = neutral, publickeytoken = NULL is not marked as serializable.

The error message clearly indicates that the class voucher is not marked as serializable.

Add the serializableattribute of voucher. Next, we will test the multi-state array. Modify testserializevouchers and testdeserializevouchers as follows:

[Test]

Public   Void Testserializevouchers ()

{

Voucher [] vouchers =   New Voucher [] { New Voucher ( " 2005012900001 " , " Xingd " , Datetime. Now ), New Billvoucher ( " 2005020400001 " , " 2005012900001 " , " Xingd " , Datetime. Now )} ;


Voucherserializer serializer =   New Voucherserializer ();

Serializer. batchserialize ( " Voucher. dat " , Vouchers );

}


[Test]

Public   Void Testdeserializevouchers ()

{

Voucherserializer serializer =   New Voucherserializer ();

Voucher [] vouchers = Serializer. batchdeserialize ( " Voucher. dat " );


Assert. areequal (vouchers. length, 2 );

Assert. areequal (vouchers [ 0 ]. Voucherid, " 2005012900001 " );

Assert. areequal (vouchers [ 0 ]. Creator, " Xingd " );

Assert. areequal (vouchers [ 1 ]. GetType (), Typeof (Billvoucher ));

Assert. areequal (billvoucher) Vouchers [ 1 ]). Billid, " 2005020400001 " );

Assert. areequal (vouchers [ 1 ]. Voucherid, " 2005012900001 " );

Assert. areequal (vouchers [ 1 ]. Creator, " Xingd " );

}


After running, both tests pass. The generated voucher. dat content is as follows:

Based on voucher. Data, we can draw the following conclusions:

    1. Binaryformatter serialization is based on the object's dynamic type.
    2. When a derived class is serialized, the field of the base class is identified by base + field.
    3. During binaryformatter serialization of an object, only one output containing assembly information is generated for the same assembly in the graph formed by the object referenced by the object, only one output containing the type information is generated for the same type.

Interestingly, there is a seemingly redundant generalledger in the line 00000060. the voucher string is used to record the static type information of vouchers, that is, voucher []. The type information of voucher [] may be composed of the type information of voucher and an array identifier. When we analyze the file format generated during the serialization implementation process, we will verify this guess. If you are interested, you can verify it yourself.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.