Freigeben über


ISerializable-Schnittstelle

Ermöglicht einem Objekt, die eigene Serialisierung und Deserialisierung zu überwachen.

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

Syntax

'Declaration
<ComVisibleAttribute(True)> _
Public Interface ISerializable
'Usage
Dim instance As ISerializable
[ComVisibleAttribute(true)] 
public interface ISerializable
[ComVisibleAttribute(true)] 
public interface class ISerializable
/** @attribute ComVisibleAttribute(true) */ 
public interface ISerializable
ComVisibleAttribute(true) 
public interface ISerializable

Hinweise

Alle Klassen, die möglicherweise serialisiert werden, müssen mit dem SerializableAttribute markiert werden. Wenn eine Klasse die eigene Serialisierung überwachen muss, kann diese die ISerializable-Schnittstelle implementieren. Der Formatter ruft während der Serialisierung GetObjectData auf und füllt die angegebene SerializationInfo mit allen zur Darstellung des Objekts erforderlichen Daten. Der Formatter erstellt eine SerializationInfo mit dem Typ des Objekts im Diagramm. Objekte, die Proxys senden müssen, können die übertragenen Informationen mithilfe der FullTypeName-Methode und der AssemblyName-Methode für die SerializationInfo ändern.

Im Fall der Klassenvererbung kann eine Klasse, die von einer Basisklasse abgeleitet ist, die ISerializable implementiert, serialisiert werden. In diesem Fall sollte die abgeleitete Klasse die Basisklassenimplementierung von GetObjectData in ihrer Implementierung von GetObjectData aufrufen. Andernfalls werden die Daten von der Basisklasse nicht serialisiert.

Die ISerializable-Schnittstelle impliziert einen Konstruktor mit der Signatur Konstructor(SerializationInfo-Informationen, StreamingContext-Kontext). Während der Deserialisierung wird der aktuelle Konstruktor erst aufgerufen, nachdem die Daten in der SerializationInfo vom Formatierungsprogramm deserialisiert wurden. Dieser Konstruktor sollte i. d. R. geschützt sein, sofern die Klasse nicht versiegelt ist.

Die Reihenfolge, in der Objekte deserialisiert werden, kann nicht garantiert werden. Wenn beispielsweise ein Typ auf einen noch nicht deserialisierten Typ verweist, tritt eine Ausnahme auf. Beim Erstellen von Typen mit derartigen Abhängigkeiten umgehen Sie dieses Problem, indem Sie die IDeserializationCallback-Schnittstelle und die OnDeserialization-Methode implementieren.

Die Serialisierungsarchitektur behandelt Objekttypen, die MarshalByRefObject erweitern, wie Typen, die Object erweitern. Diese Typen können wie alle anderen Objekttypen mit dem SerializableAttribute markiert werden und die ISerializable-Schnittstelle implementieren. Der Objektzustand der Typen wird aufgezeichnet und im Stream gespeichert.

Wenn diese Typen über System.Runtime.Remoting verwendet werden, stellt die Remotinginfrastruktur einen Ersatz bereit, der Vorrang vor der normalen Serialisierung hat und stattdessen einen Proxy in das MarshalByRefObject serialisiert. Ein Ersatz ist eine Hilfsfunktion, die Objekte eines bestimmten Typs serialisieren und deserialisieren kann. Der Proxy, der den Benutzern i. d. R. nicht sichtbar ist, ist vom Typ ObjRef.

In allgemein üblichen Entwurfsmustern wird eine Klasse, die MarshalByRefObject erweitert, i. d. R. nicht mit dem serializable-Attribut markiert Entwickler sollten bei der Kombination dieser beiden Merkmale die möglichen Serialisierungs- und Remoteszenarien genau überdenken. Eine Anwendungsmöglichkeit ist z. B. ein MemoryStream. Obwohl die Basisklasse von MemoryStream (Stream) eine Erweiterung von MarshalByRefObject ist, kann der Zustand eines MemoryStream nach Belieben aufgezeichnet und wiederhergestellt werden. Es kann deshalb sinnvoll sein, den Zustand dieses Streams in eine Datenbank zu serialisieren und zu einem späteren Zeitpunkt wiederherzustellen. Objekte dieses Typs würden jedoch in einer Remotesituation über ein Proxy übermittelt werden.

Weitere Informationen über die Serialisierung von Klassen, die MarshalByRefObject erweitern, finden Sie unter RemotingSurrogateSelector. Weitere Informationen über das Implementieren von ISerializable finden Sie unter Benutzerdefinierte Serialisierung.

Hinweise für Implementierer Implementieren Sie diese Schnittstelle, damit ein Objekt an der eigenen Serialisierung und Deserialisierung teilnehmen kann.

Beispiel

Im folgenden Codebeispiel wird die Definition eines benutzerdefinierten Serialisierungsverhaltens einer Klasse mithilfe der ISerializable-Schnittstelle veranschaulicht.

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.
      info.SetType(GetType(SingletonSerializationHelper))
      ' 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()
        Run()
    End Sub

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

        Try
            ' 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)
            Throw
        Finally
            fs.Close()
        End Try

    End Sub
End Class
using System;
using System.Web;
using System.IO;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Security.Permissions;


// There should be only one instance of this type per AppDomain.
[Serializable]
public sealed class Singleton : ISerializable 
{
    // This is the one instance of this type.
    private static readonly Singleton theOneObject = new Singleton();

    // Here are the instance fields.
    private string someString_value;
    private Int32 someNumber_value;

   public string SomeString
   {
       get{return someString_value;}
       set{someString_value = value;}
   }

   public Int32 SomeNumber
   {
       get{return someNumber_value;}
       set{someNumber_value = value;}
   }

    // Private constructor allowing this type to construct the Singleton.
    private Singleton() 
    { 
        // Do whatever is necessary to initialize the Singleton.
        someString_value = "This is a string field";
        someNumber_value = 123;
    }

    // A method returning a reference to the Singleton.
    public static Singleton GetSingleton() 
    { 
        return theOneObject; 
    }

    // A method called when serializing a Singleton.
    [SecurityPermissionAttribute(SecurityAction.LinkDemand, 
    Flags=SecurityPermissionFlag.SerializationFormatter)]
    void ISerializable.GetObjectData(
        SerializationInfo info, StreamingContext context) 
    {
        // Instead of serializing this object, 
        // serialize a SingletonSerializationHelp instead.
        info.SetType(typeof(SingletonSerializationHelper));
        // No other values need to be added.
    }

    // Note: ISerializable's special constructor is not necessary 
    // because it is never called.
}


[Serializable]
internal sealed class SingletonSerializationHelper : IObjectReference 
{
    // This object has no fields (although it could).

    // GetRealObject is called after this object is deserialized.
    public Object GetRealObject(StreamingContext context) 
    {
        // When deserialiing this object, return a reference to 
        // the Singleton object instead.
        return Singleton.GetSingleton();
    }
}


class App 
{
    [STAThread]
    static void Main() 
    {
        FileStream fs = new FileStream("DataFile.dat", FileMode.Create);

        try 
        {
            // Construct a BinaryFormatter and use it 
            // to serialize the data to the stream.
            BinaryFormatter formatter = new BinaryFormatter();

            // Create an array with multiple elements refering to 
            // the one Singleton object.
            Singleton[] a1 = { Singleton.GetSingleton(), Singleton.GetSingleton() };

            // This displays "True".
            Console.WriteLine(
                "Do both array elements refer to the same object? " + 
                (a1[0] == a1[1]));     

            // Serialize the array elements.
            formatter.Serialize(fs, a1);

            // Deserialize the array elements.
            fs.Position = 0;
            Singleton[] a2 = (Singleton[]) formatter.Deserialize(fs);

            // This displays "True".
            Console.WriteLine("Do both array elements refer to the same object? " 
                + (a2[0] == a2[1])); 

            // This displays "True".
            Console.WriteLine("Do all array elements refer to the same object? " 
                + (a1[0] == a2[0]));
        }   
        catch (SerializationException e) 
        {
            Console.WriteLine("Failed to serialize. Reason: " + e.Message);
            throw;
        }
        finally 
        {
            fs.Close();
        }
    }
}
using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;
using namespace System::Runtime::Serialization;

ref class SingletonSerializationHelper;

// There should be only one instance of this type per AppDomain.

[Serializable]
public ref class Singleton sealed: public ISerializable
{
private:

   // This is the one instance of this type.
   static Singleton^ theOneObject = gcnew Singleton;

public:

   // Here are the instance fields.
   String^ someString;
   Int32 someNumber;

private:

   // Private constructor allowing this type to construct the singleton.
   Singleton()
   {
      
      // Do whatever is necessary to initialize the singleton.
      someString = "This is a String* field";
      someNumber = 123;
   }

public:

   // A method returning a reference to the singleton.
   static Singleton^ GetSingleton()
   {
      return theOneObject;
   }

   // A method called when serializing a Singleton.
   [System::Security::Permissions::SecurityPermissionAttribute
   (System::Security::Permissions::SecurityAction::LinkDemand, 
   Flags=System::Security::Permissions::SecurityPermissionFlag::SerializationFormatter)]
   virtual void GetObjectData( SerializationInfo^ info, StreamingContext context )
   {
      // Instead of serializing this Object*, we will  
      // serialize a SingletonSerializationHelp instead.
      info->SetType( SingletonSerializationHelper::typeid );

      // No other values need to be added.
   }

   // NOTE: ISerializable*'s special constructor is NOT necessary 
   // because it's never called
};

[Serializable]
private ref class SingletonSerializationHelper sealed: public IObjectReference
{
public:

   // This Object* has no fields (although it could).
   // GetRealObject is called after this Object* is deserialized
   virtual Object^ GetRealObject( StreamingContext context )
   {
      // When deserialiing this Object*, return a reference to 
      // the singleton Object* instead.
      return Singleton::GetSingleton();
   }
};

[STAThread]
int main()
{
   FileStream^ fs = gcnew FileStream( "DataFile.dat",FileMode::Create );
   try
   {
      // Construct a BinaryFormatter and use it 
      // to serialize the data to the stream.
      BinaryFormatter^ formatter = gcnew BinaryFormatter;

      // Create an array with multiple elements refering to 
      // the one Singleton Object*.
      array<Singleton^>^a1 = {Singleton::GetSingleton(),Singleton::GetSingleton()};

      // This displays S"True".
      Console::WriteLine( "Do both array elements refer to the same Object? {0}", (a1[ 0 ] == a1[ 1 ]) );

      // Serialize the array elements.
      formatter->Serialize( fs, a1 );

      // Deserialize the array elements.
      fs->Position = 0;
      array<Singleton^>^a2 = (array<Singleton^>^)formatter->Deserialize( fs );

      // This displays S"True".
      Console::WriteLine( "Do both array elements refer to the same Object? {0}", (a2[ 0 ] == a2[ 1 ]) );

      // This displays S"True".
      Console::WriteLine( "Do all  array elements refer to the same Object? {0}", (a1[ 0 ] == a2[ 0 ]) );
   }
   catch ( SerializationException^ e ) 
   {
      Console::WriteLine( "Failed to serialize. Reason: {0}", e->Message );
      throw;
   }
   finally
   {
      fs->Close();
   }

   return 0;
}

Plattformen

Windows 98, Windows 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

.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen.

Versionsinformationen

.NET Framework

Unterstützt in: 2.0, 1.1, 1.0

Siehe auch

Referenz

ISerializable-Member
System.Runtime.Serialization-Namespace
RemotingSurrogateSelector-Klasse

Weitere Ressourcen

XML- und SOAP-Serialisierung
Benutzerdefinierte Serialisierung