C++ Tip: Serializing .NET Objects with Managed C++

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

Serialization is the mechanism by which objects are written to disk in binary form. It is a quick and easy means of saving and retrieving your data without using a database. Serialization is ideal in situations where an application needs to persist current state information or user preferences. This installment of the .NET Tips & Techniques column illustrates how to serialize entire objects—as well as selected members—to and from disk.

Defining a Class as Serializable

To specify that an entire object is to be serialized, the first thing you need to do is annotate the desired class with the Serializable attribute. Note that each member of the class will be serialized by default. Here's an example of defining a class to be serialized:

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

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; }
};

Writing Objects to Disk

Now, take a look at the client code that you would use to serialize an example class called Programmer:

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

...

FileStream* stream = NULL;

try
{
  Programmer* programmer = new Programmer("Joe", "Smith", 24);

  stream = new FileStream(S"programmer.dat", FileMode::Create,
                          FileAccess::ReadWrite);

  BinaryFormatter* formatter = new BinaryFormatter();
  formatter->Serialize(stream, programmer);
}
catch(Exception* e)
{
  throw e;
}
__finally
{
  if (NULL != stream) stream->Close();
}

Reading Objects from Disk

Now, observe how to "deserialize"—or read—the data back from the file:

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

...

FileStream* stream = NULL;

try
{
  stream = new FileStream(S"Programmer.dat", FileMode::Open,
                          FileAccess::ReadWrite);

  BinaryFormatter* formatter = new BinaryFormatter();
  programmer = static_cast<Programmer*>(formatter->
                                        Deserialize(stream));
}
catch(Exception* e)
{
  throw e;
}
__finally
{
  if (NULL != stream) stream->Close();
}

Using the NonSerialized Attribute

Sometimes, you will want to serialize only selected members of a given object. For example, you might not want to serialize information that the user must supply each time, such as a password or credit card information. Another example would be if the application uses remoting, where bandwidth and performance naturally are a concern, and you do not want to serialize any members that are necessary for the remoting process. The easiest—and least flexible—way to specify that you do not want to serialize a given member is to simply annotate it by using the NonSerialized attribute:

[Serializable]
__gc class Programmer
{
...

protected:
 String* firstName;
 String* lastName; 
 [NonSerialized]Int32 age;

...
};

If you serialize the object to disk and read it back, the Programmer::Age member will have a value of 0 because it was omitted from the serialization process. Note that value types are initialized to 0, whereas reference types are initialized to null.

Summary

This week's tip illustrated the process of serializing entire objects by using the Serializable attribute along with the FileStream and BinaryFormatter classes. In addition, it covered using the NonSerialized attribute to specify that a given member not be serialized. The next installment will take this a step further and show how to use the ISerializable interface for much more control over the serialization process.



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.

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