给定类更改,在序列化之间键入对象

时间:2019-05-01 09:33:36

标签: c# serialization types

我正在将类型相关的信息存储在字典中,例如

Dictionary<Type, int> TypeInformation;

TypeInformation[typeof(OneOfMyOwnClasses)] = 42;

然后,我(二进制)对应用程序的状态进行序列化,包括上面的字典。

如果我在代码中更改OneOfMyOwnClasses ,类型对象会怎样?反序列化后,在什么条件下类型对象保持不变?即什么时候

if (TypeInformation[typeof(OneOfMyOwnClasses)] == 42)
    MessageBox.Show("Yahoo !!!");

即使我反序列化了应用程序的状态后,仍然给出肯定的结果吗?

  • 是否更改了方法主体以确保在不同的运行之间提供相同类型的对象?
  • 更改私有方法或字段名称是否会更改有关类型对象的任何内容?
  • 公用方法(或字段)名称的更改?
  • 更改名称空间或程序集?
  • 更改类名本身? (据说不是... ;-))

最后,考虑到所有这些,是否有充分的理由不序列化类型信息,并且有更好的,更复杂的方式(例如创建GUID等)吗?

1 个答案:

答案 0 :(得分:1)

假设您的意思是BinaryFormatter,然后:

  1. 如果要存储类型的实例或Type对象本身,则更改类型的类型,名称空间或程序集标识将破坏序列化程序
  2. 更改类型上的字段的名称或类型会破坏序列化程序,如果您要存储该类型的实例

在两种情况下,都有一些方法可以通过跳过复杂的箍来解决它,但是尝试通常不是一个好主意。根据我的经验,BinaryFormatter根本不是一个好选择,除非在非常特定的情况下(尤其是两个运行中的应用程序之间的RPC,这些应用程序必须运行完全相同的代码-例如应用程序域隔离),并且如果您的意图是通用的存储,通常最好使用其他任何方式。我特别倾向于protobuf-net(它是“二进制”的,因为它实现了Google的二进制“协议缓冲区”格式),但是我承认有偏见。就可移植性而言,JSON和XML也是不错的选择,尽管它们几乎总是具有更大的输出和(略微)较慢的处理。

请注意,大多数序列化程序在对Type对象进行序列化时,将使用完全限定的名称,因此,尽管第个序列化器采用逐序列化方式,但上面的第1点将适用于大多数序列化程序。 >更改可能存在。坦率地说,我想说的是,如果您要序列化一个Type实例,那么您做错了什么,最好将其作为手动键查找一些外部引用(例如,可以通过类型上的属性)。例如:

[SomeMarker("abc")]
class OneOfMyOwnClasses {...}

然后使用反射(以某种缓存的方式)获取SomeMarkerAttribute实例,以便您实际存储:

Type type = ...
string key = GetMarkerFromType(type); // "abc"
Dictionary<string, int> TypeInformation;
TypeInformation[key] = 42;