如何仅序列化某些对象属性

ale*_*2k8 5 .net serialization

鉴于此类对象:

Foo foo = new Foo
{
    A = "a",
    B = "b",
    C = "c",
    D = "d"
};
Run Code Online (Sandbox Code Playgroud)

如何仅序列化和反序列化某些属性(例如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" }
Run Code Online (Sandbox Code Playgroud)

我使用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" }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

有任何想法吗?

此外,可能有一些更好或现有的替代品?

编辑:

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

编辑2:

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

Wya*_*ett 24

非常简单 - 只需使用[ScriptIgnore]属性装饰您想要忽略的方法.

  • 然后你从错误的角度看这个 - 本机序列化是关于序列化对象.可能最好的选择是创建两个对象 - 一个用于A和B,一个用于C和D,然后根据需要序列化它们中的任何一个. (4认同)

小智 5

过去我自己也用 Javascript Serializer 做过类似的事情。在我的情况下,我只想序列化包含值的对象中的可为空属性。我通过使用反射,检查属性的值并将该属性添加到字典中来做到这一点,例如

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;
}
Run Code Online (Sandbox Code Playgroud)

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