.NET序列化:如何选择性地忽略数据字段 [英] .net serialization: how to selectively ignore data fields

查看:112
本文介绍了.NET序列化:如何选择性地忽略数据字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在。网你可以标记一个字段作为非序列化,并且化期间,将跳过。

In. Net you can mark a field as non serializable, and it will be skipped during serialization.

我在找一个简单的方法,让我在运行时控制特定字段是否应序列。

I'm looking for a simple method that will allow me to control in runtime whether a specific field should be serialized.

推荐答案

您指的是标记字段作为非序列化,所以我假设你正在使用的BinaryFormatter [非序列化] 。如果是这样,只有这样才能做到的条件的序列化是通过实施 ISerializable的并添加了类似的构造函数,并把逻辑在 GetObjectData使用的实施。这是繁琐且容易出错,虽然。我建议在看protobuf网,里面有简单的条件系列化,使用由 TypeDescriptor 标准模式和的XmlSerializer ,但仍然是二进制输出(比的BinaryFormatter 更有效,实际上)。具体做法是:

You are referring to "mark a field as non serializable", so I assume you are using BinaryFormatter and [NonSerialized]. If so, the only way to do conditional serialization is by implementing ISerializable and adding a similar constructor, and putting the logic in the GetObjectData implementation. This is tedious and error prone, though. I would suggest looking at protobuf-net, which has simpler conditional serialization, using the standard patterns used by TypeDescriptor and XmlSerializer, but is still binary output (more efficient than BinaryFormatter, actually). Specifically:

[ProtoContract]
public class SomeType {
    [ProtoMember(1)]
    public string Name {get;set;}

    private bool ShouldSerializeName() {
       // return true to serialize Name, false otherwise
    }
}

ShouldSerialize * 是一个标准的基于名称的约定 - 没有什么特定于该串行

This ShouldSerialize* is a standard name-based convention - nothing specific to this serializer.

下面是通过相同的 ISerializable的

[Serializable]
public class SomeType : ISerializable
{
    public SomeType() { }
    public string Name { get; set; }


    void ISerializable.GetObjectData(
             SerializationInfo info, StreamingContext context)
    {
        if (/* should serialize Name */) info.AddValue("Name", Name);
        //... all other fields
    }
    protected SomeType(SerializationInfo info, StreamingContext context)
    {
        foreach (SerializationEntry entry in info)
        {
            switch (entry.Name)
            {
                case "Name": Name = (string)entry.Value; break;
                //... all other fields
            }
        }
    }
}

很多更多的维护;特别是,你必须在使用 ISerializable的来承担所有成员的责任 - 不过,如果你只是使用protobuf网,你可以处理每一个案件逐案的基础。

Lots more to maintain; in particular, you have to take responsibility for all members when using ISerializable - however, if you just use protobuf-net you can handle each on a case-by-case basis.

其实,你可以混合和匹配也是如此,也就是说,如果你被卡住使用的BinaryFormatter ,你仍然可以卸载工作,protobuf网,但<强>它会改变格式(所以不会与旧的数据兼容)。例如:

Actually, you can mix-and-match too, i.e. if you are stuck with using BinaryFormatter, you can still offload the work to protobuf-net, but it will change the format (so won't be compatible with old data). For example:

[Serializable, ProtoContract]
public class SomeType : ISerializable
{
    public SomeType() { }
    [ProtoMember(1)]
    public string Name { get; set; }
    private bool ShouldSerializeName() { /* condition */ }

    void ISerializable.GetObjectData(
        SerializationInfo info, StreamingContext context)
    {
        Serializer.Serialize(info, this); 
    }
    protected SomeType(SerializationInfo info, StreamingContext context)
    {
        Serializer.Merge(info, this);
    }
}

这篇关于.NET序列化:如何选择性地忽略数据字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆