【问题标题】:How to serialize only certain object properties如何仅序列化某些对象属性
【发布时间】:2009-06-04 12:25:25
【问题描述】:

给定这样的对象:

Foo foo = new Foo
{
    A = "a",
    B = "b",
    C = "c",
    D = "d"
};

如何仅序列化和反序列化某些属性(例如 A 和 D)。

Original: 
  { A = "a", B = "b", C = "c", D = "d" }

Serialized:
  { A = "a", D = "d" }

Deserialized:
  { A = "a", B = null, C = null, D = "d" }

我使用 System.Web.Extensions.dll 中的 JavaScriptSerializer 编写了一些代码:

public string Serialize<T>(T obj, Func<T, object> filter)
{
    return new JavaScriptSerializer().Serialize(filter(obj));
}

public T Deserialize<T>(string input)
{
    return new JavaScriptSerializer().Deserialize<T>(input);
}

void Test()
{
    var filter = new Func<Foo, object>(o => new { o.A, o.D });

    string serialized = Serialize(foo, filter);
    // {"A":"a","D":"d"}

    Foo deserialized = Deserialize<Foo>(serialized);
    // { A = "a", B = null, C = null, D = "d" }
}

但我希望反序列化器的工作方式有所不同:

Foo output = new Foo
{
    A = "1",
    B = "2",
    C = "3",
    D = "4"
};

Deserialize(output, serialized);
// { A = "a", B = "2", C = "3", D = "d" }

有什么想法吗?

另外,是否有更好的或现有的替代品可用?

编辑:

有一些建议使用属性来指定可序列化的字段。我正在寻找更动态的解决方案。所以我可以序列化 A、B 和下一次 C、D。

编辑 2:

任何序列化解决方案(JSON、XML、Binary、Yaml...)都可以。

【问题讨论】:

    标签: .net serialization


    【解决方案1】:

    非常简单——只需使用[ScriptIgnore] 属性装饰您希望忽略的方法即可。

    【讨论】:

    • 我希望它更有活力。所以我可以序列化 A、B 或 C、D。
    • 那么你从错误的角度来看这个——原生序列化是关于序列化对象的。最好的办法可能是创建两个对象——一个用于 A 和 B,一个用于 C 和 D,然后根据需要对它们中的任何一个进行序列化。
    【解决方案2】:

    我过去曾用 Javascript 序列化器做过类似的事情。就我而言,我只想序列化包含值的对象中的可为空属性。我通过使用反射、检查属性的值并将属性添加到字典来做到这一点,例如

    public static Dictionary<string,object> CollectFilledProperties(object instance)
    {
        Dictionary<string,object> filledProperties = new Dictionary<string,object>();
        object data = null;
    
        PropertyInfo[] properties = instance.GetType().GetProperties();
        foreach (PropertyInfo property in properties)
        {
            data = property.GetValue(instance, null);
    
            if (IsNullable(property.PropertyType) && data == null)
            {
                // Nullable fields without a value i.e. (still null) are ignored.
                continue;
            }
    
            // Filled has data.
            filledProperties[property.Name] = data;
        }
    
        return filledProperties;
    }
    
    public static bool IsNullable(Type checkType)
    {
        if (checkType.IsGenericType && checkType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            // We are a nullable type - yipee.
            return true;
        }
        return false;
    }
    

    然后你传递字典而不是序列化原始对象,而 bob 是你的叔叔。

    【讨论】:

      【解决方案3】:

      有些属性可以应用于控制序列化的类和/或属性。 Attributes that control serialization.

      【讨论】:

        【解决方案4】:

        [NonSerialized()] 属性标签呢?

            class Foo  
            {
                field A;
        
                [NonSerialized()]
                field B;
        
                [NonSerialized()]
                field C;
        
                field D;  
            }
        

        【讨论】:

        • 这适用于二进制序列化。给出的示例是 Java 脚本序列化。我不确定它是否适用于那种类型。
        • JavaScriptSerializer 的等效属性是 [ScriptIgnore()]。
        猜你喜欢
        • 2023-03-29
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        • 2015-04-23
        • 1970-01-01
        • 2011-08-13
        • 1970-01-01
        • 2020-04-11
        相关资源
        最近更新 更多