【问题标题】:Conditional C# Binary Serialization条件 C# 二进制序列化
【发布时间】:2010-09-06 03:31:34
【问题描述】:

我正在使用 BinaryFormatter 按条件序列化一个类及其变量。例如:

[Serializable]
public class Class1
{
private Class2 B;
...
}

[Serializable]
public class Class2{...}

我希望变量 B 仅在远程处理时被序列化,而不是在我将其序列化到文件存储时。 问题:
1) 我知道在 XmlSerialization 中我们可以使用 [XmlIgnore] 和 {PropertyName}Specified 有条件地忽略该属性。这是 [NonSerialized] 的等效方法吗?
2) 对于具有[Serializable]属性的类,如何在运行时忽略它?

【问题讨论】:

    标签: c# binary-serialization


    【解决方案1】:
    1. 没有这样的方法。您可以通过实现ISerializable 来控制序列化,如果这样做,您将知道哪个序列化上下文处于活动状态(远程处理、文件等)
    2. AFAIK 没办法,你为什么要这个?

    一般来说,我建议您不要使用BinaryFormatter。如果有的话,这是一个令人头疼的维护问题。使用 XML 序列化或某种协议缓冲区。

    【讨论】:

    • 非常感谢。对于我的情况,实现 ISerializable 太繁琐了,因为类和变量太多。我对protobuf感兴趣。它还允许自定义序列化吗?因为我在 GetObjectData() 期间转换了一些值。
    • 您不必在所有类中实现 ISerializable,只需在您想要自定义逻辑的那些类中实现。 Protobuf 应该允许自定义序列化,但我不肯定它会满足您的需求;如果您的数据架构足够规则,也许您最好重新考虑您的数据架构或生成自定义序列化代码(即关于何时应该序列化什么有明确的规则,并且很少有例外)。
    【解决方案2】:
    1. 如前所述,它不存在。您可以编写自己的方式,尽管它有点混乱(也就是说,如果您不想像已经建议的那样实现 ISerializable 接口)。

      [Serializable]
      public class ClassA
      {
          [OnSerializing]
          private void OnSerializing(StreamingContext context)
          {
              //Set BSerialized = B based on context or some internal boolean
              BSerialized = B;
          }
          [OnSerialized]
          private void OnSerialized(StreamingContext context)
          {
              //Clear BSerialized
              BSerialized = null;
          }
          [OnDeserialized]
          private void OnDeserialized(StreamingContext context)
          {
              //Restore B from BSerialized
              B = BSerialized;
              BSerialized = null;
          }
          [NonSerialized]
          private ClassB B;
          private ClassB BSerialized;
      }
      [Serializable]
      public class ClassB { }
      
    2. 你不能忽视它。您只能在运行时更改属性的属性,并且由于 NonSerialized 属性不接受 true / false 参数,因此您无法在运行时对其执行任何操作。

    【讨论】:

      【解决方案3】:

      我编写了一个相当简单但可扩展的框架来使用绑定来解决这类问题。不确定我是否完全理解,但这是可能的:

      public class Class1
      {
        [Ignore]
        public bool IsRemoting { get; set; }
      
        [SerializeWhen("IsRemoting", true)]
        public Class2 B;
      }
      

      http://binaryserializer.codeplex.com

      【讨论】:

        猜你喜欢
        • 2016-07-27
        • 2017-10-18
        • 1970-01-01
        • 2010-12-17
        • 2015-09-17
        • 2016-02-21
        • 1970-01-01
        • 2011-06-08
        • 2012-06-15
        相关资源
        最近更新 更多