Managed Extensions: Implementing Custom Serialization

Welcome to this week's installment of .NET Tips & Techniques! Each week, award-winning Architect and Lead Programmer Tom Archer demonstrates how to perform a practical .NET programming task using either C# or Managed C++ Extensions.

In an earlier installment of .NET Tips & Techniques, I illustrated how to serialize your __gc classes—as well as selected member variables—to and from disk. In this week's tip, I'll illustrate a technique called custom serialization, which will give you far greater control over serializing your object's contents than the simple Serializable and NonSerialized attributes covered in the earlier article.

The ISerializable Interface

You realize custom serialization by implementing the ISerializable interface. This interface contains only one method—GetObjectData—which the Formatter object automatically calls during serialization. This process gives you complete control over how each member is serialized—including the ability to perform any pre- or post-processing.

Here's the syntax for the ISerializable::GetObjectData method:

void ISerializable::GetObjectData(SerializationInfo* info,
                                  StreamingContext context);

The basic functionality of this method is to populate the SerializationInfo object with the data needed to perform serialization, where the StreamingContext specifies the destination for the serialization. You typically won't need to manipulate the StreamingContext parameter because it has already been initialized for you. It's passed to you for the rare occasion when you need to know the ultimate destination of the object's data.

Here's a simple example of how to use this interface:

using namespace System::IO;
using namespace System::Runtime::Serialization;
using namespace System::Runtime::Serialization::Formatters::Binary;
...

[Serializable]
__gc class Programmer : public ISerializable
{
public:
  Programmer(String* firstName, String* lastName, Int32 age)
  {
    this->firstName = firstName;
    this->lastName = lastName;
    this->age = age;
  }

protected:
  Programmer(SerializationInfo *si, StreamingContext sc)
  {
    this->firstName = si->GetString(S"firstName");
    this->lastName  = si->GetString(S"lastName");
    // Note that this->Age is not read because it was never written
  }

protected:
  String* firstName;
  String* lastName; 
  Int32 age;

public:
  __property String* get_FirstName() { return this->firstName; }
  __property String* get_LastName() { return this->lastName; }
  __property Int32 get_Age() { return this->age; }

public:
  void GetObjectData(SerializationInfo *si, StreamingContext sc)
  {
    si->AddValue(S"firstName", this->firstName);
    si->AddValue(S"lastName", this->lastName);
    // Note that this->Age is not being saved here
  }
};

As you can see, a bit of work needs to be done—but it's not much and certainly isn't difficult. The first thing to note is the addition of a second (protected) constructor. This constructor is called automatically during serialization and enables you to have full control over which members are set and how. As you can see, you retrieve the value read from disk by calling the SerializationInfo::GetString method. Each supported type has a distinct method (such as GetString, GetInt32, GetInt64, and so forth).

The second thing to note is the GetObjectData method. Here, I'm simply calling the overloaded SerializationInfo::AddValue method for each member that I want written to disk. In this case, I'm intentionally omitting the Programmer::Age member because I don't care to serialize its value.

You'll also notice that the client code for serializing and de-serializing an object is exactly the same as in the earlier article. In other words, the addition of custom serialization has no impact on the client code.

Complete Control Over Serialization

Custom serialization gives you complete control over the serialization process while requiring you to implement only two methods—ISerializable::GetObjectData (for writing) and an additional constructor (for reading).

A word to the wise if you're mixing MFC and Managed Extensions: Trying to serialize MFC objects with .NET serialization is far more trouble than it's worth. It's better to serialize MFC objects by using the standard CArchive-based MFC serialization technique and use custom serialization only for .NET (or __gc) classes.



About the Author

Tom Archer - MSFT

I am a Program Manager and Content Strategist for the Microsoft MSDN Online team managing the Windows Vista and Visual C++ developer centers. Before being employed at Microsoft, I was awarded MVP status for the Visual C++ product. A 20+ year veteran of programming with various languages - C++, C, Assembler, RPG III/400, PL/I, etc. - I've also written many technical books (Inside C#, Extending MFC Applications with the .NET Framework, Visual C++.NET Bible, etc.) and 100+ online articles.

Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: November 20, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Are you wanting to target two or more platforms such as iOS, Android, and/or Windows? You are not alone. 90% of enterprises today are targeting two or more platforms. Attend this eSeminar to discover how mobile app developers can rely on one IDE to create applications across platforms and approaches (web, native, and/or hybrid), saving time, money, and effort and introducing apps to market faster. You'll learn the trade-offs for gaining long …

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds