gpt4 book ai didi

c# - .NET 反序列化与 OnDeserializing 和 OnDeserialized

转载 作者:可可西里 更新时间:2023-11-01 02:58:44 28 4
gpt4 key购买 nike

我使用一个可序列化的简单类。它有一个用于反序列化的构造函数:

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)

最佳答案

Now both methods get called before the constructor gets called

不,顺序是:

  • OnDeserializingMethod
  • .ctor
  • OnDeserializedMethod

And how can a (non-static) method be called before any constructor has been executed?

因为它欺骗和说谎;它不使用构造函数创建对象;不完全是。它使用 FormatterServices.GetUninitializedObject 分配 Vanilla 空白空间。然后,如果有自定义反序列化构造函数,它会在该对象的顶部调用构造函数。可恶的。像这样,基本上:

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]);

IMO 他们可能应该将此作为 ISerializable 接口(interface)上的第二个方法,但出于某种原因:他们没有这样做。真的很遗憾:这会让它更诚实,并且避免人们需要记住实现自定义构造函数。

示例输出:

.ctor: MyClass
> serializing
OnSerializingMethod: MyClass
GetObjectData: MyClass
OnSerializedMethod: MyClass
< serializing
> deserializing
OnDeserializingMethod: MyClass
.ctor: MyClass
OnDeserializedMethod: MyClass
< deserializing

示例代码:

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

关于c# - .NET 反序列化与 OnDeserializing 和 OnDeserialized,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18377046/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com