다음을 통해 공유


ISerializable 인터페이스

개체가 자체 serialization 및 deserialization을 제어할 수 있도록 합니다.

네임스페이스: System.Runtime.Serialization
어셈블리: mscorlib(mscorlib.dll)

구문

‘선언
<ComVisibleAttribute(True)> _
Public Interface ISerializable
‘사용 방법
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

설명

serialize될 수 있는 클래스는 SerializableAttribute를 사용하여 표시해야 합니다. 클래스가 자신의 serialization 프로세스를 제어해야 하는 경우에는 ISerializable 인터페이스를 구현하면 됩니다. Formatter는 serialization 도중에 GetObjectData를 호출하며 개체를 나타내는 데 필요한 모든 데이터로 제공된 SerializationInfo를 채웁니다. Formatter는 그래프에 있는 개체의 형식을 가진 SerializationInfo를 만듭니다. 자체 프록시를 보내야 하는 개체는 SerializationInfo에 대한 FullTypeNameAssemblyName 메서드를 사용하여, 전송된 정보를 변경할 수 있습니다.

클래스 상속의 경우 ISerializable을 구현하는 기본 클래스에서 파생되는 클래스를 serialize할 수 있습니다. 이 경우 파생 클래스에서는 해당 클래스가 구현하는 GetObjectData 내에서 GetObjectData를 호출해야 합니다. 그렇지 않으면 기본 클래스의 데이터가 serialize되지 않습니다.

ISerializable 인터페이스는 생성자를 시그니처 생성자(SerializationInfo 정보, StreamingContext 컨텍스트)와 함께 포함합니다. deserialization을 수행하는 경우에는 SerializationInfo의 데이터가 포맷터에 의해 deserialize된 후에만 현재 생성자가 호출됩니다. 일반적으로 클래스가 봉인 클래스가 아닌 경우에는 이 생성자를 보호해야 합니다.

개체가 deserialize되는 순서는 보장할 수 없습니다. 예를 들어, 한 형식이 아직 deserialize되지 않은 형식을 참조할 경우 예외가 발생합니다. 이러한 종속 관계가 있는 형식을 만들 경우 IDeserializationCallback 인터페이스 및 OnDeserialization 메서드를 구현하여 문제를 해결할 수 있습니다.

serialization 아키텍처는 MarshalByRefObject를 확장하는 개체 형식을 Object를 확장하는 형식과 동일하게 처리합니다. 이러한 형식은 SerializableAttribute로 표시할 수 있으며 ISerializable 인터페이스를 다른 개체 형식으로 구현할 수 있습니다. 해당 개체의 상태는 캡처되어 스트림에 유지됩니다.

이러한 형식을 System.Runtime.Remoting을 통해 사용하고 있는 경우 원격 인프라는 일반 serialization을 획득하고 대신에 프록시를 MarshalByRefObject에 serialize하는 서로게이트를 제공합니다. 서로게이트는 특정 형식의 개체를 serialize 및 deserialize하는 방법에 대해 알고 있는 도우미입니다. 프록시는 대부분의 경우에 사용자가 볼 수 없으며 ObjRef 형식을 가집니다.

일반적인 디자인 경향을 고려할 때, 한 클래스가 serializable 특성을 사용하여 표시되면서 동시에 MarshalByRefObject를 확장하는 경우는 드뭅니다. 개발자는 이 두 특징을 조합할 때 예상되는 serialization 및 원격 작업 시나리오를 신중하게 고려해야 합니다. 예를 들어, MemoryStream이 이 경우에 해당됩니다. MemoryStream의 기본 클래스(Stream)를 MarshalByRefObject로부터 확장하는 동안 MemoryStream의 상태를 캡처하여 자유롭게 복원할 수 있습니다. 따라서 이 스트림의 상태를 데이터베이스에 serialize하여 나중에 복원하는 것도 좋습니다. 하지만 원격을 통해 사용되는 경우 이 형식의 개체는 프록시됩니다.

MarshalByRefObject를 확장하는 클래스의 serialization에 대한 자세한 내용은 RemotingSurrogateSelector를 참조하십시오. ISerializable 구현에 대한 자세한 내용은 사용자 지정 Serialization를 참조하십시오.

구현자 참고 사항 이 인터페이스를 구현하면 개체가 자체 serialization 및 deserialization에 참여할 수 있습니다.

예제

다음 코드 예제는 클래스에 대한 사용자 지정 serialization 동작을 정의하기 위한 ISerializable 인터페이스의 사용에 대해 설명합니다.

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;
}

플랫폼

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에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.

버전 정보

.NET Framework

2.0, 1.1, 1.0에서 지원

참고 항목

참조

ISerializable 멤버
System.Runtime.Serialization 네임스페이스
RemotingSurrogateSelector 클래스

기타 리소스

XML 및 SOAP Serialization
사용자 지정 Serialization