ISerializable Interface

Allows an object to control its own serialization and deserialization.

Namespace: System.Runtime.Serialization
Assembly: mscorlib (in mscorlib.dll)

<ComVisibleAttribute(True)> _
Public Interface ISerializable
Dim instance As ISerializable

/** @attribute ComVisibleAttribute(true) */ 
public interface ISerializable
public interface ISerializable
Not applicable.

Any class that might be serialized must be marked with the SerializableAttribute. If a class needs to control its serialization process, it can implement the ISerializable interface. The Formatter calls the GetObjectData at serialization time and populates the supplied SerializationInfo with all the data required to represent the object. The Formatter creates a SerializationInfo with the type of the object in the graph. Objects that need to send proxies for themselves can use the FullTypeName and AssemblyName methods on SerializationInfo to change the transmitted information.

In the case of class inheritance, it is possible to serialize a class that derives from a base class that implements ISerializable. In this case, the derived class should call the base class implementation of GetObjectData inside its implementation of GetObjectData. Otherwise, the data from the base class will not be serialized.

The ISerializable interface implies a constructor with the signature constructor (SerializationInfo information, StreamingContext context). At deserialization time, the current constructor is called only after the data in the SerializationInfo has been deserialized by the formatter. In general, this constructor should be protected if the class is not sealed.

The order in which objects are deserialized cannot be guaranteed. For example, if one type references a type that has not been deserialized yet, an exception will occur. If you are creating types that have such dependencies, you can work around the problem by implementing the IDeserializationCallback interface and the OnDeserialization method.

The serialization architecture handles object types that extend MarshalByRefObject the same as types that extend Object. These types can be marked with the SerializableAttribute and implement the ISerializable interface as any other object type. Their object state will be captured and persisted onto the stream.

When these types are being used through System.Runtime.Remoting, the remoting infrastructure provides a surrogate that preempts typical serialization and instead serializes a proxy to the MarshalByRefObject. A surrogate is a helper that knows how to serialize and deserialize objects of a particular type. The proxy, invisible to the user in most cases, will be of type ObjRef.

As a general design pattern, it would be unusual for a class to be both marked with the serializable attribute and extend MarshalByRefObject. Developers should think carefully about the possible serialization and remoting scenarios when combining these two characteristics. One example where this might be applicable is with a MemoryStream. While the base class of MemoryStream (Stream) extends from MarshalByRefObject, it is possible to capture the state of a MemoryStream and restore it at will. It might, therefore, be meaningful to serialize the state of this stream into a database and restore it at some later point in time. However, when used through remoting, an object of this type would be proxied.

For more information about serialization of classes that extend MarshalByRefObject, see RemotingSurrogateSelector. For more information about implementing ISerializable, see Custom Serialization.

Notes to Implementers: Implement this interface to allow an object to take part in its own serialization and deserialization.

The following code example demonstrates the use of the ISerializable interface to define custom serialization behavior for a class.

Imports System
Imports System.Web
Imports System.IO
Imports System.Collections
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Runtime.Serialization
Imports System.Security.Permissions

' There should be only one instance of this type per AppDomain.
<Serializable()> _
Public NotInheritable Class Singleton
   Implements ISerializable

   ' This is the one instance of this type.
   Private Shared ReadOnly theOneObject As New Singleton

   ' Here are the instance fields.
   Public someString As String
   Public someNumber As Int32

   ' Private constructor allowing this type to construct the Singleton.
   Private Sub New()
      ' Do whatever is necessary to initialize the Singleton.
      someString = "This is a string field"
      someNumber = 123
   End Sub

   ' A method returning a reference to the Singleton.
   Public Shared Function GetSingleton() As Singleton
      Return theOneObject
   End Function

   ' A method called when serializing a Singleton.
   <SecurityPermissionAttribute(SecurityAction.LinkDemand, _
   Flags:=SecurityPermissionFlag.SerializationFormatter)> _
   Private Sub GetObjectData(ByVal info As SerializationInfo, _
      ByVal context As StreamingContext) _
      Implements ISerializable.GetObjectData

      ' Instead of serializing this object, we will  
      ' serialize a SingletonSerializationHelp instead.
      ' No other values need to be added.
   End Sub

   ' Note: ISerializable's special constructor is not necessary 
   ' because it is never called.
End Class

<Serializable()> _
Friend NotInheritable Class SingletonSerializationHelper
   Implements IObjectReference
   ' This object has no fields (although it could).

   ' GetRealObject is called after this object is deserialized.
   Public Function GetRealObject(ByVal context As StreamingContext) As Object Implements IObjectReference.GetRealObject
      ' When deserialiing this object, return a reference to 
      ' the Singleton object instead.
      Return Singleton.GetSingleton()
   End Function
End Class

Class App
   <STAThread()> Shared Sub Main()
    End Sub

    Shared Sub Run()
        Dim fs As New FileStream("DataFile.dat", FileMode.Create)

            ' Construct a BinaryFormatter and use it 
            ' to serialize the data to the stream.
            Dim formatter As New BinaryFormatter

            ' Create an array with multiple elements refering to 
            ' the one Singleton object.
            Dim a1() As Singleton = {Singleton.GetSingleton(), Singleton.GetSingleton()}

            ' This displays "True".
            Console.WriteLine("Do both array elements refer to the same object? " & _
               Object.ReferenceEquals(a1(0), a1(1)))

            ' Serialize the array elements.
            formatter.Serialize(fs, a1)

            ' Deserialize the array elements.
            fs.Position = 0
            Dim a2() As Singleton = DirectCast(formatter.Deserialize(fs), Singleton())

            ' This displays "True".
            Console.WriteLine("Do both array elements refer to the same object? " & _
               Object.ReferenceEquals(a2(0), a2(1)))

            ' This displays "True".
            Console.WriteLine("Do all array elements refer to the same object? " & _
               Object.ReferenceEquals(a1(0), a2(0)))
        Catch e As SerializationException
            Console.WriteLine("Failed to serialize. Reason: " & e.Message)
        End Try

    End Sub
End Class

Windows 98, Windows Server 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

The Microsoft .NET Framework 3.0 is supported on Windows Vista, Microsoft Windows XP SP2, and Windows Server 2003 SP1.

.NET Framework

Supported in: 3.0, 2.0, 1.1, 1.0