.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的主要内容,如果未能解决你的问题,请参考以下文章

加密 .NET 二进制序列化流

protobuf.net 和条件序列化

如何在一组行之后或有条件地在没有 PL/SQL 块的情况下增加 oracle 序列?

给定十六进制代码的查找,如何有条件地格式化 Shiny 中的文本?

有条件地 [JsonIgnore]

如何有条件地包含一个库