Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






How to Define a Type That ImplementsISerializable When the Base Type Doesn’t Implement This Interface

As mentioned earlier, the ISerializable interface is extremely powerful, because it allows a type to take complete control over how instances of the type get serialized and deserialized. However, this power comes at a cost: The type is now responsible for serializing all of its base type’s fields as well. Serializing the base type’s fields is easy if the base type also implements the ISerializable inter- face; you just call the base type’s GetObjectData method.

However, someday, you may find yourself defining a type that needs to take control of its serial- ization, but whose base type does not implement the ISerializable interface. In this case, your derived class must manually serialize the base type’s fields by grabbing their values and adding them to the SerializationInfo collection. Then, in your special constructor, you will also have to get the values out of the collection and somehow set the base class’s fields. Doing all of this is easy (albeit

tedious) if the base class’s fields are public or protected, but it can be very difficult or impossible to do if the base class’s fields are private.

This following code shows how to properly implement ISerializable’s GetObjectData method

and its implied constructor so that the base type’s fields are serialized.

 

[Serializable] internal class Base {

protected String m_name = "Jeff";

public Base() { /* Make the type instantiable */ }

}

 

[Serializable]

internal sealed class Derived : Base, ISerializable { private DateTime m_date = DateTime.Now;

public Derived() { /* Make the type instantiable*/ }

 

// If this constructor didn't exist, we'd get a SerializationException

// This constructor should be protected if this class were not sealed [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] private Derived(SerializationInfo info, StreamingContext context) {

// Get the set of serializable members for our class and base classes Type baseType = this.GetType().BaseType;

MemberInfo[] mi = FormatterServices.GetSerializableMembers(baseType, context);



 

// Deserialize the base class's fields from the info object for (Int32 i = 0; i < mi.Length; i++) {

// Get the field and set it to the deserialized value FieldInfo fi = (FieldInfo)mi[i];

fi.SetValue(this, info.GetValue(baseType.FullName + "+" + fi.Name, fi.FieldType));

}

 

// Deserialize the values that were serialized for this class m_date = info.GetDateTime("Date");

}


[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {

// Serialize the desired values for this class info.AddValue("Date", m_date);

 

// Get the set of serializable members for our class and base classes Type baseType = this.GetType().BaseType;

MemberInfo[] mi = FormatterServices.GetSerializableMembers(baseType, context);



 

// Serialize the base class's fields to the info object for (Int32 i = 0; i < mi.Length; i++) {

// Prefix the field name with the fullname of the base type info.AddValue(baseType.FullName + "+" + mi[i].Name,

((FieldInfo)mi[i]).GetValue(this));

}

}

public override String ToString() {

return String.Format("Name={0}, Date={1}", m_name, m_date);

}

}

 

In this code, there is a base class, Base, which is marked only with the SerializableAttribute custom attribute. Derived from Base is Derived, which also is marked with the Serializable­ Attribute attribute and also implements the ISerializable interface. To make the situation more interesting, you’ll notice that both classes define a String field called m_name. When calling SerializationInfo’s AddValue method, you can’t add multiple values with the same name. The preceding code handles this situation by identifying each field by its class name prepended to the field’s name. For example, when the GetObjectData method calls AddValue to serialize Base’s m_name field, the name of the value is written as “Base+m_name.”

 

 


Date: 2016-03-03; view: 933


<== previous page | next page ==>
Nbsp;   Controlling the Serialized/Deserialized Data | Nbsp;   Streaming Contexts
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.007 sec.)