CHAPTER 20 FILE I/O AND OBJECT SERIALIZATION
Types that implement the ISerializable interface must also define a special constructor that takes
the following signature:
// You must supply a custom constructor with this signature
// to allow the runtime engine to set the state of your object.
[Serializable]
class SomeClass : ISerializable
{
protected SomeClass (SerializationInfo si, StreamingContext ctx) {...}
...
}
Notice that the visibility of this constructor is set as protected. This is permissible because the
formatter will have access to this member, regardless of its visibility. These special constructors tend to
be marked as protected (or private for that matter) to ensure that the casual object user can never create
an object in this manner. The first parameter of this constructor is an instance of the SerializationInfo
type (which you’ve seen previously).
The second parameter of this special constructor is a StreamingContext type, which contains
information regarding the source of the bits. The most informative member of StreamingContext is the
State property, which represents a value from the StreamingContextStates enumeration. The values of
this enumeration represent the basic composition of the current stream.
Unless you intend to implement some low-level custom remoting services, you will seldom need to
deal with this enumeration directly. Nevertheless, here are the possible names of the
StreamingContextStates enum (consult the .NET Framework 4.5 SDK documentation for full details):
public enum StreamingContextStates
{
CrossProcess,
CrossMachine,
File,
Persistence,
Remoting,
Other,
Clone,
CrossAppDomain,
All
}
Now let’s look at how to customize the serialization process using ISerializable. Assume you have
a new Console Application project (named CustomSerialization) that defines a class type containing two
points of string data. Also assume that you must ensure that the string objects are serialized to the
stream in all uppercase, and deserialized from the stream in lowercase. To account for such rules, you
could implement ISerializable like this (be sure to import the System.Runtime.Serialization
namespace):
[Serializable]
class StringData : ISerializable
{
private string dataItemOne = "First data block";
private string dataItemTwo= "More data";
public StringData(){}
protected StringData(SerializationInfo si, StreamingContext ctx)
797