Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаба №1 / books / csharp_ebook.pdf
Скачиваний:
77
Добавлен:
03.03.2016
Размер:
3.69 Mб
Скачать

Programmers Heaven: C# School

Console.WriteLine("DeSerializing the object....

");

Addition sum = (Addition) binForm.Deserialize(fs);

The BinaryFormatter class’ Deserialize() method takes the file stream as its parameter, reads the object graph from it and returns an object of type System.Object. We have to explicitly cast it to the desired class. Once we have got the object, we call the Add() method of the class which uses the private members of the class to compute the sum and print the result on the console

int res = sum.Add();

Console.WriteLine("The sum of 3 and 4 is: {0}", res);

When you compile and execute the program, you will see the following output:

Serializing the object....

DeSerializing the object....

The sum of 3 and 4 is: 7

Press any key to continue

If you comment just the [Serializable] attribute over the Addition class definition, you will get an exception when Serialize() method of the BinaryFormatter is called. Try it!

//[Serializable] class Addition

{

...

Formatters in Serialization

A formatter describes the format in which an object is serialized. The formatter should be standard and both the serializing and deserializing parties must use the same or a compatible formatter. In .Net, a formatter needs to implement the System.Runtime.Serialization.IFormatter interface. The two common formatters are the Binary Formatter (System.Runtime.Serialization.Formatters.Binary.BinaryFormatter) and the SOAP Formatter (System.Runtime.Serialization.Formatters.Soap.SoapFormatter). The SOAP (Simple Object Access Protocol) is a standard protocol over the internet and has got the support of Microsoft, IBM and other industry giants. The Binary Formatter is more optimized for a local system.

Preventing certain elements from Serializing – The [NonSerialized] attribute

You can prevent the CLR from serializing certain fields when serializing an object. There may be different reasons for that. You might decide on it for security purposes or if you want to save disk space by not writing some long

312

Programmers Heaven: C# School

irrelevant fields. For this you simply need to mark the field with the [NonSerialized] attribute. For example, let us change the result field to [NonSerialized]. The complete source code of the modified program is:

using System;

 

using

System.IO;

// for FileStream

using

System.Runtime.Serialization.Formatters.Binary; // for BinaryFormatter

namespace Compiler

{

class Test

{

static void Main()

{

Addition addition = new Addition(3, 4); addition.Add();

Console.WriteLine("The value of result is: {0}", addition.Result);

FileStream fs = new FileStream(@"C:\C-Sharp.txt", FileMode.Create);

BinaryFormatter binForm = new BinaryFormatter();

Console.WriteLine("Serializing the object...."); binForm.Serialize(fs, addition);

fs.Position = 0; // move to the start of file

Console.WriteLine("DeSerializing the object....");

Addition sum = (Addition) binForm.Deserialize(fs);

Console.WriteLine("The value of result is: {0}", sum.Result);

Console.WriteLine("The sum of addition is: {0}", sum.Add());

}

}

[Serializable] class Addition

{

private int num1; private int num2; [NonSerialized] private int result;

313

Programmers Heaven: C# School

public Addition()

{

}

public Addition(int num1, int num2)

{

this.num1 = num1; this.num2 = num2;

}

public int Add()

{

result = num1 + num2; return result;

}

public int Result

{

get { return result; }

}

}

}

Note the [NonSerialized] attribute over the result field. Now consider the Main() method of the program. We first create an instance of the Addition class with two numbers, call its Add() method to compute the result and print it.

Addition addition = new Addition(3, 4);

addition.Add();

Console.WriteLine("The value of result is: {0}", addition.Result);

We then serialize the object and deserialize it back to another object, just like in the previous example:

FileStream fs = new FileStream(@"C:\C-Sharp.txt", FileMode.Create);

BinaryFormatter binForm = new BinaryFormatter();

Console.WriteLine("Serializing the object...."); binForm.Serialize(fs, addition);

fs.Position = 0; // move to the start of file

Console.WriteLine("DeSerializing the object....");

314

Programmers Heaven: C# School

Addition sum = (Addition) binForm.Deserialize(fs);

Now consider the next steps. First we print the value of the result variable using the Result property.

Console.WriteLine("The value of result is: {0}", sum.Result);

If the value of Result is not serialized, the above line should print zero. Finally we print the result of the addition

Console.WriteLine("The sum of addition is: {0}", sum.Add());

The above line should print the sum of 3 and 4 if the variables num1 and num2 were serialized. When we compile and execute the program, we get the following result.

The value of result is: 7

Serializing the object....

DeSerializing the object....

The value of result is: 0

The sum of addition is: 7

Press any key to continue.

In the output, we can see that the value of the result field after deserializtiaon is zero, suggesting that the field result is not serialized with the object. The value of result (3+4=7) after calling the Add() method suggests that the fields num1 and num2 did get serialized with the object. Hence, we can prevent some of our fields from serializing with the object.

Getting notified when Deserializing - the IDeserializationCallBack interface

When we don’t want some of our fields to serialize with the object, we may like to perform some work on the object when deserializing so that we may prepare non-serialized fields. For example, we may like to compute the result variable of the Addition class when deserializing the object. For this, we need to implement the IDeserializationCallBack interface. The interface only contains one method

void OnDeserialization(object sender);

This method is always called in the implementing class when the object is deserialized. Let's change the previous application so that result variable retains its value even if it is not serialized. The modified source code is:

using System;

 

 

using System.IO;

// for FileStream

using

System.Runtime.Serialization;

// for IDeserializationCallBack

using

System.Runtime.Serialization.Formatters.Binary; // for BinaryFormatter

namespace Compiler

315

Programmers Heaven: C# School

{

class Test

{

static void Main()

{

Addition addition = new Addition(3, 4); addition.Add();

Console.WriteLine("The value of result is: {0}", addition.Result);

FileStream fs = new FileStream(@"C:\C-Sharp.txt", FileMode.Create); BinaryFormatter binForm = new BinaryFormatter();

Console.WriteLine("Serializing the object...."); binForm.Serialize(fs, addition);

fs.Position = 0; // move to the start of file

Console.WriteLine("DeSerializing the object....");

Addition sum = (Addition) binForm.Deserialize(fs);

Console.WriteLine("The value of result is: {0}", sum.Result);

}

}

[Serializable]

class Addition : IDeserializationCallback

{

private int num1; private int num2; [NonSerialized] private int result;

public Addition()

{

}

public Addition(int num1, int num2)

{

this.num1 = num1; this.num2 = num2;

}

316

Programmers Heaven: C# School

public int Add()

{

result = num1 + num2; return result;

}

public int Result

{

get { return result; }

}

public void OnDeserialization(object sender)

{

result = num1 + num2;

}

}

}

Note that this time the class Addition inherits the IDeserializationCallback interface and provides the definition of the OnDeserialization method in which it computes the sum of num1 and num2 and stores it in the result field:

public void OnDeserialization(object sender)

{

result = num1 + num2;

}

The Main() method is very similar to the one in the previous program but this time we should not get a zero value in the result field after deserialization if the OnDeserialization method is called. When we compile and execute the above program, we see the following result:

The value of result is: 7

Serializing the object....

DeSerializing the object....

The value of result is: 7

Press any key to continue

The result shows that the OnDeserialization() method is actually called when deserialization is performed as we did not get the zero value of the result fields after deserialization.

317

Соседние файлы в папке books