.NET 二进制序列化有条件地没有 ISerializable
Posted
技术标签:
【中文标题】.NET 二进制序列化有条件地没有 ISerializable【英文标题】:.NET binary serialization conditionally without ISerializable 【发布时间】:2011-06-05 05:09:16 【问题描述】:我有 2 节课,例如:
public class A
private B b;
...
public class B
...
我需要使用 BinaryFormatter 序列化对象 A。远程处理时应包括字段 b,但序列化到文件时不包括。这是我添加的内容:
[Serializable]
public class A : MarshalByRefObject
private B b;
[OnSerializing]
private void OnSerializing(StreamingContext context)
if (context.State == StreamingContextStates.File)
this.b = null;
...
[Serializable]
public class B : MarshalByRefObject
...
我认为这是一个糟糕的设计,因为如果另一个类 C 也包含 B,那么在 C 类中我们必须像在 A 中一样添加重复的 OnSerializing() 逻辑。B 类应该决定做什么,而不是 A 类或 C 类。
我不想使用 ISerializable 接口,因为 B 类中有太多变量必须添加到 SerializationInfo 中。
我可以为 B 类创建一个 SerializationSurrogate,它在 GetObjectData() 和 SetObjectData() 中不执行任何操作,然后在序列化到文件时使用它。然而,同样的维护问题,因为无论谁修改 B 类都无法注意到序列化过程中会发生什么以及 SerializationSurrogate 的存在。
还有更好的选择吗?
【问题讨论】:
使用MarshalByRefObject
,远程时它不序列化...
【参考方案1】:
真正的问题是使用Serializable
(我试图序列化)一个MarshalByRefObject
派生类型,如果对象位于另一个域中,这几乎是不可能的。
使用其中一个,但不能同时使用。
【讨论】:
感谢您的回复。远程处理时使用 MarshalByRefObject,文件序列化时使用 [Serializable]。我已经测试了这两种共存作品没有问题。 另外,我不认为 MarshalByRefObject 可以序列化到文件。 谢谢,我记得我在尝试此操作时遇到了很多问题,但您的情况可能与我尝试的情况大不相同。 但是从它派生出来的还是MarshalByRefObject
。它是如何被序列化的(如果不归档)。
1) 如果没有 [Serializable],当序列化到文件时会抛出异常,例如“B 类未标记为可序列化...” 2) MarshalByRefObject 允许跨应用程序域引用对象时远程处理。【参考方案2】:
好的,我对 MarshalByRefObject 有误解。它不序列化,因此我可以使用 [NonSerializable] 进行文件序列化。
尽管如此,我确实有一些标有 [Serializable] 的类,以便在远程处理时按值编组。因此需要将其与文件序列化区分开来:
[Serializable]
public class A
private B b;
[OnSerializing]
private void OnSerializing(StreamingContext context)
if (context.State == StreamingContextStates.File)
this.b = null;
...
[Serializable]
public class B
...
[NonSerialized] 在这种情况下没有帮助,因为: 1) 远程处理时需要序列化字段 b,但不需要序列化到磁盘。 2) 如果类 C、D、E 等也有字段 b,则必须使用 [NonSerialized] 更新所有这些字段。维护任务过多。
还有更好的选择吗?
【讨论】:
以上是关于.NET 二进制序列化有条件地没有 ISerializable的主要内容,如果未能解决你的问题,请参考以下文章
如何在一组行之后或有条件地在没有 PL/SQL 块的情况下增加 oracle 序列?