namespace Cars
{
[Serializable]
public class Car
{
private string cubicCentimeter;
public string Color
{ get; set; }
public string Model
{ get; set; }
public int NoOfDoors
{ get; set; }
public int Price
{ get; set; }
}
}
We have seen and talked about the Car class n number of times in my other blogs so I will skip and move over, it is a very simple class with a private member variable and four public properties which are making use of Automatic Properties. Please note the Serializable attribute at the top of the class. The Seializable attribute has to be applied to any type which needs to be serialized into a binary form. If the attribute is missing from the type then the compiler will throw a “System.Runtime.SerializatType 'CLASS/TYPE NAME' in Assembly 'ASSEMBLY NAME, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializableThe code to serialize the Car object into a Binary stream is as shown below.
BinaryFormatter binFor = new BinaryFormatter();
using (System.IO.FileStream fs = new System.IO.FileStream("CarObject", System.IO.FileMode.Create))
{
Cars.Car car = new Cars.Car { Model = "BMW 7 Series", Color = "Red", NoOfDoors = 4 };
binFor.Serialize(fs, car);
}
In the above code we are making use of the BinaryFormatter class to serialize the Car class to a Binary stream. One can see I am making use of Object Initializers to initialize the Car object. Once the car object is initialized I am calling the Serialize method of BinaryFormatter class and passing the Car object along with the FileStream object as arguments. All the members of the Car objects are serialized and dumped into the FileStream object. Even the private variable “cubicCentimeter” of the Car class is serialized to the file stream object. The byte stream generated by the BinaryFormatter class for the Car class is pasted below.
ÿÿÿÿ JSerializationSample, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null Cars.Car cubicCentimeter<Color>k__BackingField<Model>
k__BackingField<NoOfDoors>k__BackingField<Price>
k__BackingField Red BMW 7 Series
One can see from the above stream that all the public properties along with their values have been serialized. Even the private member variable (highlighted in Red) has been serialized.
namespace Cars
{
[Serializable]
public class Car
{
[NonSerialized]
private string cubicCentimeter;
public string Color
{ get; set; }
public string Model
{ get; set; }
public int NoOfDoors
{ get; set; }
public int Price
{ get; set; }
public string ClassName()
{
return this.GetType().ToString();
}
}
}
The serialized content with the NonSerialized attribute applied is pasted below.
ÿÿÿÿ JSerializationSample, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null Cars.Car <Color>k__BackingField<Model>k__BackingField<NoOfDoors>
k__BackingField<Price>k__BackingField Red
BMW 7 Series
If you compare the above serialized content with the previous one you can find out that the content is not having the private member variable “cubicCentimeter”.
Attribute 'NonSerialized' is not valid on this declaration type. It is only valid on 'field' declarations.So if you want to prevent your public properties from getting binary serialized then you cannot use Automatic Properties, instead you have to go with the good old ways of declaring properties where you declare a private member variable which will hold the value of the property and then use the NonSerialized attribute on that member variable or you can write custom serialization by implementing ISerializable interface which we will see in my subsequent blog. The sample code below shows how to restrict public property from getting serialized using the NonSerialized attribute on the member variable storing the property value.
namespace Cars
{
[Serializable]
public class Car
{
[NonSerialized]
private string cubicCentimeter;
public string Color
{ get; set; }
public string Model
{ get; set; }
public int NoOfDoors
{ get; set; }
[NonSerialized]
private int price;
public int Price
{
get
{
return price;
}
set
{
price = value;
}
}
public string ClassName()
{
return this.GetType().ToString();
}
}
}
Now when the above class is serialized it will be devoid of the public property Price. The byte stream is pasted below
ÿÿÿÿ JSerializationSample, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null Cars.Car <Color>k__BackingField<Model>k__BackingField<NoOfDoors>
k__BackingField Red BMW 7 Series
So using the NoSerilaized attribute we can control a particular member of a class from getting serialized.
using (System.IO.FileStream fs = new System.IO.FileStream("CarObject", System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
BinaryFormatter deSerialize = new BinaryFormatter();
Cars.Car car = (Cars.Car)deSerialize.Deserialize(fs);
}
In the above code FileStream object is used to read the binary content from a file and then the DeSerialize method of BinaryFormatter is used to deserialize the object to its state before serialization. The below screenshot shows all the properties of the Car class being read from the binary file and assigned.
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (1)
Commented: