.NET Framework 類別庫
ISerializable 介面

更新:2007 年 11 月

允許物件控制它自己的序列化 (Serialization) 和還原序列化 (Deserialization)。

命名空間:  System.Runtime.Serialization
組件:  mscorlib (在 mscorlib.dll 中)
語法

Visual Basic (宣告)
<ComVisibleAttribute(True)> _
Public Interface ISerializable
Visual Basic (使用方式)
Dim instance As ISerializable
C#
[ComVisibleAttribute(true)]
public interface ISerializable
Visual C++
[ComVisibleAttribute(true)]
public interface class ISerializable
J#
/** @attribute ComVisibleAttribute(true) */
public interface ISerializable
JScript
public interface ISerializable
備註

任何可能要序列化的類別必須使用 SerializableAttribute 加以標記。如果某類別需要控制它自己的序列化程序,則它可以實作 ISerializable 介面。Formatter 會在序列化時呼叫 GetObjectData,並將表示物件所需的所有資料填入提供的 SerializationInfo 中。Formatter 會使用 Graph 中的物件型別建立 SerializationInfo。需要為自己傳送 Proxy 的物件可以使用在 SerializationInfo 上的 FullTypeNameAssemblyName 方法來變更所傳輸的資訊。

若為類別繼承關係,可以序列化衍生自實作 ISerializable 之基底類別 (Base Class) 的類別。在這種情況下,衍生類別 (Derived Class) 應該在其 GetObjectData 的實作中呼叫 GetObjectData 的基底類別實作。否則,不會序列化基底類別的資料。

ISerializable 介面表示具有簽章建構函式的建構函式 (SerializationInfo 資訊,StreamingContext 內容)。在還原序列化期間,目前的建構函式只有在 SerializationInfo 中的資料已經由格式子 (Formatter) 還原序列化後才呼叫。如果類別不是密封的,則通常應該保護這個建構函式。

無法保證還原序列化物件的順序。例如,如果一種型別參考尚未還原序列化的型別,則會發生例外狀況。如果您正在建立具有這樣相依性的型別,則可透過實作 IDeserializationCallback 介面和 OnDeserialization 方法解決這個問題。

序列化架構以處理擴充 Object 的型別的相同方式來處理擴充 MarshalByRefObject 的物件型別。這些型別可以使用 SerializableAttribute 加以標記,並將 ISerializable 介面實作為任何其他的物件型別。它們的物件狀態將會擷取並保存至資料流上。

當這些型別透過 System.Runtime.Remoting 使用時,遠端基礎結構會提供代理,該代理會優先於一般序列化,並改將 Proxy 序列化至 MarshalByRefObject。代理是知道如何序列化和還原序列化特定型別物件的 Helper。在多數狀況中無法為使用者所見的 Proxy 將屬於型別 ObjRef

做為一般的設計模式,如果類別是使用可序列化屬性和延伸 MarshalByRefObject 加以標記,則狀況不尋常。開發人員應該在結合這兩個特性時,仔細思考可能的序列化和遠端案例。這種狀況的類似範例是使用 MemoryStream。當 MemoryStream ( Stream ) 的基底類別延伸自 MarshalByRefObject 時,有可能會擷取 MemoryStream 的狀態,並任意將它還原。因此,若要將這個資訊流的狀態序列化為資料庫並稍後還原才有意義。不過,如果這個型別的物件經由遠端使用,則將可以代理。

如需擴充 MarshalByRefObject 之類別序列化的詳細資訊,請參閱 RemotingSurrogateSelector。如需實作 ISerializable 的詳細資訊,請參閱 自訂序列化

實作器注意事項

實作這個介面,以便允許物件參與它自己的序列化和還原序列化。

範例

下列程式碼範例將展示 ISerializable 介面定義類別自訂序列化行為的用法。

Visual Basic
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
C#
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();
        }
    }
}
Visual C++
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;
}
平台

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

.NET Framework 和 .NET Compact Framework 並不支援各種平台的所有版本。如需支援平台版本的相關資訊,請參閱 .NET Framework 系統需求
版本資訊

.NET Framework

支援版本:3.5、3.0、2.0、1.1、1.0
請參閱

參考

其他資源

標記 :


Page view tracker