C # serialization of classes: general solutions and final questions

Source: Internet
Author: User

Some time ago, due to frequent usage of class serialization, I have been thinking about how to use this function more conveniently. Now I will share my learning process for a while with you, if you are already familiar with class serialization, please read the third part directly.

What is class serialization? To put it bluntly, an instance of a class is converted into XML or binary data for network transmission and storage operations.
Likewise, deserialization is to restore an XML or binary description object to a class instance.

Starting serialization
In C #, it is not difficult to implement class serialization. in XML serialization, for example, we first declare a class:
[Serializable]
Public class myclass
{
......
}
The class declaration above [serializable] is used to indicate that this class can be serialized, and then
Reference two namespaces:

Using system. IO;
Using system. xml. serialization;

Then you can execute the following code:

 

1 code
2 myclass CLS = new myclass ();
3 xmlserializer = new xmlserializer (CLS. GetType ());
4 memorystream stream = new memorystream ();
5xmlserializer. serialize (stream, CLS );
6 byte [] Buf = stream. toarray ();
7 string xml = encoding. ASCII. getstring (BUF );
8stream. Close ();

Since then, the serialization has been completed, and the XML sequence is stored in the string XML; variable.
The above code is hard to understand. The xmlserializer class is used to provide the XML serialization function. The xmlserializer. serialize (stream, CLS) method can serialize the class CLs and store the XML sequence in the stream.
The above is the basic method of serialization, which can meet our needs. But the problem is that if we often need to serialize and deserialize several classes, we need to repeat the above Code frequently. Can we make the classes have their own serialization methods?

I. First Attempt
First of all, I thought that I could write a base class that provides serialization methods. Any class that wants to implement serialization only needs to inherit this class. Construct an abstract class:

 

 

1 public abstract class serializablebaseclass
2 {
3 Public Virtual string xmlserialize ()
4 {
5 xmlserializer = new xmlserializer (GetType (); // difference 1
6 memorystream stream = new memorystream ();
7 xmlserializer. serialize (stream, this); // difference 2
8 byte [] Buf = stream. toarray ();
9 string xml = encoding. ASCII. getstring (BUF );
10 stream. Close ();
11 return XML;
12}
13}

The above code is different from the previous Code in two lines:
Difference 1:
Cls. getType () is changed to GetType (): GetType () is the type used to obtain the current instance. In the base class, GetType () is called to obtain the type of the current instance, rather than the accumulated type. In other words, calling GetType () in the above base class won't get "serializablebaseclass", not "system. Object", but the type of the current object instance.

Difference 2:
CLS changes to this: Similarly, This references the current instance, but in the base class, this cannot be used to directly access subclass members. Of course, this can be achieved through type conversion, but it is not covered in this article. Therefore, serialize (stream, this) Will serialize the entire object without causing object segmentation. It only serializes the base class.

Ii. Second Attempt
So far, any class has its own serialization method as long as it integrates serializablebaseclass. But how can it be deserialized? We add another method in the serializablebaseclass class.

 

1 public object deserialize (string xmlstring)
2 {
3 xmlserializer = new xmlserializer (GetType ());
4 byte [] Buf = encoding. ASCII. getbytes (xmlstring );
5 memorystream stream = new memorystream (BUF );
6 object o = xmlserializer. deserialize (Stream );
7 return O;
8}

This method implements class deserialization. We can use this method as follows:
Statement:
[Serializable]
Public class myclass: serializablebaseclass
{
......
}
Usage:

 

1 myclass CLS = new myclass ();
2 string xml = Cls. serialize ();
3 myclass cls1 = (myclass) CLS. deserialize (XML );

 

At first glance, this is no problem, but it is very poor to use.
1. To deserialize a class, you must first create an instance of this class to call deserialize ()
2. Call deserialize () to return the object type. type conversion is required.

I have also considered these two issues for a long time. If deserialize () is defined as static, The GetType () method cannot be used, and the subclass type cannot be obtained.

Iii. Last Attempt
I have been thinking about these two problems for a long time, but I never thought of a solution until I discussed a problem in C ++ STL with my friends one day. C # also supports templates, so excited, rewrite the serializablebaseclass class:

 

1 [serializable ()]
2 public abstract class serializablebaseclass <t>
3 {
4 Public Virtual string xmlserialize ()
5 {
6 xmlserializer = new xmlserializer (GetType ());
7 memorystream stream = new memorystream ();
8 xmlserializer. serialize (stream, this );
9 byte [] Buf = stream. toarray ();
10 string xml = encoding. ASCII. getstring (BUF );
11 stream. Close ();
12 Return XML;
13}
14
15 public static t deserialize (string xmlstring)
16 {
17 xmlserializer = new xmlserializer (typeof (t ));
18 byte [] Buf = encoding. ASCII. getbytes (xmlstring );
19 memorystream stream = new memorystream (BUF );
20 t o = (t) xmlserializer. deserialize (Stream );
21 return O;
22}
23}
24

 

In this way, the problem will be solved in an imperfect way (indeed not perfect ). Why is it not perfect? Let's look at the following code:
[Serializable]
Public class myclass: serializablebaseclass <myclass>
{
......
}
Usage:
Myclass CLS = myclass. deserialize (xmldata );
It seems that the above problems have been solved, but I still feel uncomfortable, because every time I define a class that inherits serializablebaseclass, I must write my class name again and put it in the parameters of the template type. Is there a solution that allows the above-mentioned Declaration of the myclass class to use the default template parameter as its own myclass without having to write it again <myclass>? Or is there any better way? Welcome to the discussion.

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.