ISerializable 接口
允许对象控制其自己的序列化和反序列化过程。
**命名空间:**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
备注
任何可以序列化的类都必须用 SerializableAttribute 进行标记。如果某个类需要控制其序列化进程,它可以实现 ISerializable 接口。Formatter 在序列化时调用 GetObjectData,并使用表示对象所需的全部数据来填充所提供的 SerializationInfo。Formatter 使用图形中对象的类型来创建 SerializationInfo。需要自己发送代理的对象可以使用 SerializationInfo 上的 FullTypeName 和 AssemblyName 方法来更改所传输的信息。
在类继承的情况下,可以序列化从实现 ISerializable 的基类中派生的类。这种情况下,派生的类应在 GetObjectData 的实现内调用 GetObjectData 的基类实现。否则,不会序列化来自基类的数据。
ISerializable 接口表示带有 Constructor 签名(SerializationInfo 信息、StreamingContext 上下文)的构造函数。在反序列化时,仅在格式化程序已反序列化 SerializationInfo 中的数据后才调用当前构造函数。一般而言,如果该类未密封,则应保护此构造函数。
无法保证对象被反序列化的顺序。例如,如果一种类型引用尚未反序列化的类型,则会引发异常。如果创建具有这种依赖关系的类型,可以通过实现 IDeserializationCallback 接口和 OnDeserialization 方法来解决该问题。
序列化结构处理像处理扩展 Object 的类型一样,处理扩展 MarshalByRefObject 的对象类型。这些类型都可以使用 SerializableAttribute 来标记,并且可以将 ISerializable 接口实现为其他任何对象类型。它们的对象状态将被捕获并在流中持续。
当通过 System.Runtime.Remoting 使用这些类型时,远程处理结构会提供一个代理项,它将取代常用的序列化,而将代理序列化为 MarshalByRefObject。代理项是知道如何将特定类型的对象序列化和反序列化的帮助器。代理在大多数情况下对于用户不可见,其类型将是 ObjRef。
作为一种常规的设计模式,类很少会既使用可序列化属性来标记,又扩展 MarshalByRefObject。当组合这两项特性时,开发人员应仔细考虑可能的序列化和远程处理方案。MemoryStream 就是一个适用的示例。当 MemoryStream ( Stream ) 的基类从 MarshalByRefObject 扩展时,可以捕获 MemoryStream 的状态并随时将其还原。因此,这样做可能是有意义的:将该流的状态序列化到数据库中,并在稍后某一时间将其还原。但是,当通过远程处理来使用时,这种类型的对象将设置代理。
有关序列化 MarshalByRefObject 的派生类的更多信息,请参见 RemotingSurrogateSelector。有关如何实现 ISerializable 的更多信息,请参见 自定义序列化。
给实现者的说明 实现此接口,以允许对象参与其自己的序列化和反序列化过程。
示例
下面的代码示例演示如何使用 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 类