C# .NET反序列化与OnDeserialize和OnDeserialized
我使用一个可序列化的简单类。它具有反序列化的构造函数:C# .NET反序列化与OnDeserialize和OnDeserialized,c#,.net,serialization,C#,.net,Serialization,我使用一个可序列化的简单类。它具有反序列化的构造函数: protected MyClass(SerializationInfo info, StreamingContext context) 以及用于序列化的GetObjectData方法。它很好用 现在,我添加了两种方法来监视反序列化: [OnDeserializing()] internal void OnDeserializingMethod(StreamingContext context) {
protected MyClass(SerializationInfo info, StreamingContext context)
以及用于序列化的GetObjectData方法。它很好用
现在,我添加了两种方法来监视反序列化:
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context)
{
System.Diagnostics.Trace.WriteLine("OnDeserializingMethod: " + this.GetType().ToString());
}
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
{
System.Diagnostics.Trace.WriteLine("OnDeserializedMethod: " + this.GetType().ToString());
}
我想知道这些方法的调用顺序。现在在调用构造函数之前调用这两个方法。这是怎么可能的,为什么在调用(反序列化)构造函数之后不调用“OnDeserialized”方法?在执行任何构造函数之前,如何调用(非静态)方法?(我正在使用BinaryFormatter)[OnDeserialization]
指示在反序列化之前要调用的方法
[已序列化]
指示在反序列化之后要调用的方法
[OnDeserialization]方法充当反序列化的伪构造函数,并且
它对于初始化从序列化中排除的字段很有用:
protected MyClass(SerializationInfo info, StreamingContext context)
[OnDeserialized]和[OnDeserialized]
反序列化将绕过所有常规构造函数以及字段初始值设定项。
如果每个字段都参与序列化,那么这没有多大影响,但是可以
如果通过[非序列化]排除某些字段,则会出现问题
我从Albahari的书C#5.0(简而言之,第713页)中摘录了这篇文章,并在网上查看了大量的示例
描述你的问题
谢谢
现在在调用构造函数之前调用这两个方法
不,订单是:
- 连续化方法
- 博士
- OnDedMethod
FormatterServices.GetUninitializedObject
分配空间。然后,如果有自定义反序列化构造函数,它将在该对象的顶部调用该构造函数。肮脏的基本上是这样的,
var obj = FormatterServices.GetUninitializedObject(typeof(MyClass));
var ctor = obj.GetType().GetConstructor(
BindingFlags.Instance | BindingFlags.Public| BindingFlags.NonPublic,
null,
new[] { typeof(SerializationInfo), typeof(StreamingContext) },
null);
ctor.Invoke(obj, new object[2]);
在我看来,他们可能应该在ISerializable
接口上将此作为第二种方法,但不管出于什么原因:他们没有这样做。真的很遗憾:这会让它更诚实,避免人们需要记住实现自定义构造函数
示例输出:
.ctor: MyClass
> serializing
OnSerializingMethod: MyClass
GetObjectData: MyClass
OnSerializedMethod: MyClass
< serializing
> deserializing
OnDeserializingMethod: MyClass
.ctor: MyClass
OnDeserializedMethod: MyClass
< deserializing
.ctor:MyClass
>连载
OnSerializingMethod:MyClass
GetObjectData:MyClass
OnSerializedMethod:MyClass
<序列化
>反序列化
OnDeserializingMethod:MyClass
.ctor:MyClass
OnDeserializedMethod:MyClass
<反序列化
示例代码:
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
class MyClass : ISerializable
{
public MyClass() { Trace(); }
protected MyClass(SerializationInfo info, StreamingContext context) { Trace(); }
public void GetObjectData(SerializationInfo info, StreamingContext context) { Trace(); }
void Trace([CallerMemberName] string caller = null)
{
System.Console.WriteLine("{0}: {1}", caller, GetType().Name);
}
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context) { Trace(); }
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context) { Trace(); }
[OnSerializing()]
internal void OnSerializingMethod(StreamingContext context) { Trace(); }
[OnSerialized()]
internal void OnSerializedMethod(StreamingContext context) { Trace(); }
static void Main()
{
using (var ms = new MemoryStream())
{
var orig = new MyClass();
var ser = new BinaryFormatter();
System.Console.WriteLine("> serializing");
ser.Serialize(ms, orig);
System.Console.WriteLine("< serializing");
ms.Position = 0;
System.Console.WriteLine("> deserializing");
ser.Deserialize(ms);
System.Console.WriteLine("< deserializing");
}
}
}
使用系统;
使用System.IO;
使用System.Runtime.CompilerServices;
使用System.Runtime.Serialization;
使用System.Runtime.Serialization.Formatters.Binary;
[可序列化]
类MyClass:ISerializable
{
公共MyClass(){Trace();}
受保护的MyClass(SerializationInfo信息,StreamingContext上下文){Trace();}
public void GetObjectData(SerializationInfo信息,StreamingContext上下文){Trace();}
无效跟踪([CallerMemberName]字符串调用者=null)
{
System.Console.WriteLine(“{0}:{1}”,调用者,GetType().Name);
}
[正在序列化()]
内部无效OnDeserializingMethod(StreamingContext上下文){Trace();}
[OnDeserialized()]
内部void OnDeserializedMethod(StreamingContext上下文){Trace();}
[正在序列化()]
内部void OnSerializingMethod(StreamingContext上下文){Trace();}
[OnSerialized()]
内部void OnSerializedMethod(StreamingContext上下文){Trace();}
静态void Main()
{
使用(var ms=new MemoryStream())
{
var orig=新的MyClass();
var ser=新的二进制格式化程序();
System.Console.WriteLine(“>序列化”);
序列序列化(ms,orig);
System.Console.WriteLine(反序列化”);
序列反序列化(ms);
System.Console.WriteLine(<反序列化”);
}
}
}
调用顺序取决于对象是序列化树的根还是对象的某个成员,该对象也在同一对象图中序列化。通过Marc Gravell提供的扩展示例,我得到以下输出:
SerRoot.ctor
SerMember.ctor
> serializing
SerRoot.OnSerializingMethod
GetObjectData
SerMember.OnSerializingMethod
SerMember.GetObjectData
SerRoot.OnSerializedMethod
SerMember.OnSerializedMethod
< serializing
> deserializing
SerRoot.OnDeserializingMethod
SerMember.OnDeserializingMethod
SerMember.OnDeserializedMethod
SerMember.ctor(info, context)
SerRoot.ctor(info, context)
SerRoot.OnDeserializedMethod
< deserializing
SerRoot.ctor
塞尔克托
>连载
SerRoot.OnSerializingMethod
GetObjectData
SerMember.OnSerializingMethod
SerMember.GetObjectData
SerRoot.on序列化方法
SerMember.OnSerializedMethod
<序列化
>反序列化
SerRoot.OnDeserializeMethod
SerMember.OnDeserializeMethod
SerMember.OnDeserializedMethod
SerMember.ctor(信息、上下文)
SerRoot.ctor(信息、上下文)
SerRoot.OnDeserializedMethod
<反序列化
请注意,在反序列化中,SerMember.ctor是在SerMember.OnDeserializedMethod之后调用的!代码如下:
static void Main(string[] args)
{
using (var ms = new MemoryStream())
{
var orig = new SerRoot();
var ser = new BinaryFormatter();
System.Console.WriteLine("> serializing");
ser.Serialize(ms, orig);
System.Console.WriteLine("< serializing");
ms.Position = 0;
System.Console.WriteLine("> deserializing");
ser.Deserialize(ms);
System.Console.WriteLine("< deserializing");
}
}
[Serializable]
class SerRoot : ISerializable
{
public SerMember m;
public SerRoot()
{
System.Console.WriteLine("SerRoot.ctor");
m = new SerMember();
}
protected SerRoot(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine("SerRoot.ctor(info, context)");
m = info.GetValue("m", typeof(SerMember)) as SerMember;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine("GetObjectData");
info.AddValue("m", m);
}
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnDeserializingMethod"); }
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnDeserializedMethod"); }
[OnSerializing()]
internal void OnSerializingMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnSerializingMethod"); }
[OnSerialized()]
internal void OnSerializedMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnSerializedMethod"); }
}
[Serializable]
class SerMember : ISerializable
{
string text;
public SerMember()
{
System.Console.WriteLine("SerMember.ctor");
text = "test";
}
protected SerMember(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine("SerMember.ctor(info, context)");
text = info.GetString("text");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine("SerMember.GetObjectData");
info.AddValue("text", text);
}
[OnDeserializing()]
internal void OnDeserializingMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnDeserializingMethod"); }
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnDeserializedMethod"); }
[OnSerializing()]
internal void OnSerializingMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnSerializingMethod"); }
[OnSerialized()]
internal void OnSerializedMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnSerializedMethod"); }
}
static void Main(字符串[]args)
{
使用(var ms=new MemoryStream())
{
var orig=新的SerRoot();
var ser=新的二进制格式化程序();
System.Console.WriteLine(“>序列化”);
序列序列化(ms,orig);
System.Console.WriteLine(反序列化”);
序列反序列化(ms);
System.Console.WriteLine(<反序列化”);
}
}
[可序列化]
类SerRoot:ISerializable
{
公共SERM;
公共SerRoot()
{
System.Console.WriteLine(“SerRoot.ctor”);
m=新成员();
}
受保护的SerRoot(SerializationInfo信息、StreamingContext上下文)
{
System.Console.WriteLine(“SerRoot.ctor(信息,上下文)”;
m=info.GetValue(“m”,typeof(SerMember))作为SerMember;
}
public void GetObjectData(SerializationInfo信息、StreamingContext上下文)
{
System.Console.WriteLine(“GetObjectData”);
信息增值(“m”,m);
}
[3]连续