C# 构造 ISerializable 接口的正确方法?
C# proper way to construct ISerializable interface?
我最近制作了自己的自定义格式化程序,它获取一个运行时对象并以字符串格式写下它的对象图,然后获取该字符串并将其转换回运行时对象。
示例:[CustomFormatter.Btype, CustomFormatter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null==[a==5][b==0]]
在弄乱原始对象(int
、bool
、float
...之后,我尝试使用 [= 将 Bitmap
对象序列化为字符串16=] 接口,它运行良好,但是当我尝试重建对象时,出现错误 System.MissingMethodException: Constructor on type 'System.Drawing.Bitmap' not found.
如果位图没有以SerializationInfo和StreamingContext为参数的构造函数,那么如何构造继承ISerializable
接口的对象?
这部分是主要问题,但我可以包括整个代码:
private static object SeriObjConstructor(Type objType, ref string dataInfo, ref int location)
{
SerializationInfo info = new SerializationInfo(objType, new FormatterConverter());
StreamingContext context = new StreamingContext(StreamingContextStates.All);
location += serializerEntry.Length;
while (!CheckHitOperator(dataInfo, serializerExit, ref location))
{
KeyValuePair<string, Type> serializedObj = GetSerialiedName(ref dataInfo, ref location); //<name, type>
info.AddValue(serializedObj.Key, Construction(serializedObj.Value, ref dataInfo, ref location));
}
location += serializerExit.Length;
location += endClass.Length;
var instance = Activator.CreateInstance(objType, info, context); //THROWS AN ERROR
return instance;
}
如果您出于遗留 .NET Framework 的原因被迫这样做,并且您正在接管序列化引擎的角色:您可以使用 FormatterServices.GetUninitializedObject
构造原始对象。此 API 明确用于序列化之类的东西, 但 应视为 advanced/exotic 功能,需要格外小心。在某些情况下可能会发生坏事(字段未初始化等)。
老实说,在 2020 年没有使用 ISerializable
接口的正确方法 - 整个 API 已被弃用和过时,并且在 .NET Core / .NET 中未得到广泛支持5,我不建议用它开始新的工作。有关 problems/reasons 的更多详细信息,请参见:https://blog.marcgravell.com/2020/03/why-do-i-rag-on-binaryformatter.html,还有许多其他未弃用的序列化框架。
我最近制作了自己的自定义格式化程序,它获取一个运行时对象并以字符串格式写下它的对象图,然后获取该字符串并将其转换回运行时对象。
示例:[CustomFormatter.Btype, CustomFormatter, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null==[a==5][b==0]]
在弄乱原始对象(int
、bool
、float
...之后,我尝试使用 [= 将 Bitmap
对象序列化为字符串16=] 接口,它运行良好,但是当我尝试重建对象时,出现错误 System.MissingMethodException: Constructor on type 'System.Drawing.Bitmap' not found.
如果位图没有以SerializationInfo和StreamingContext为参数的构造函数,那么如何构造继承ISerializable
接口的对象?
这部分是主要问题,但我可以包括整个代码:
private static object SeriObjConstructor(Type objType, ref string dataInfo, ref int location)
{
SerializationInfo info = new SerializationInfo(objType, new FormatterConverter());
StreamingContext context = new StreamingContext(StreamingContextStates.All);
location += serializerEntry.Length;
while (!CheckHitOperator(dataInfo, serializerExit, ref location))
{
KeyValuePair<string, Type> serializedObj = GetSerialiedName(ref dataInfo, ref location); //<name, type>
info.AddValue(serializedObj.Key, Construction(serializedObj.Value, ref dataInfo, ref location));
}
location += serializerExit.Length;
location += endClass.Length;
var instance = Activator.CreateInstance(objType, info, context); //THROWS AN ERROR
return instance;
}
如果您出于遗留 .NET Framework 的原因被迫这样做,并且您正在接管序列化引擎的角色:您可以使用 FormatterServices.GetUninitializedObject
构造原始对象。此 API 明确用于序列化之类的东西, 但 应视为 advanced/exotic 功能,需要格外小心。在某些情况下可能会发生坏事(字段未初始化等)。
老实说,在 2020 年没有使用 ISerializable
接口的正确方法 - 整个 API 已被弃用和过时,并且在 .NET Core / .NET 中未得到广泛支持5,我不建议用它开始新的工作。有关 problems/reasons 的更多详细信息,请参见:https://blog.marcgravell.com/2020/03/why-do-i-rag-on-binaryformatter.html,还有许多其他未弃用的序列化框架。