Free mag vol1 | Page 851

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