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

.net 如何仅序列化某些对象属性,.net,serialization,.net,Serialization,鉴于这种目的: Foo foo = new Foo { A = "a", B = "b", C = "c", D = "d" }; 如何仅序列化和反序列化某些属性(例如A和D) 我使用System.Web.Extensions.dll中的JavaScriptSerializer编写了一些代码: public string Serialize<T>(T obj, Func<T, object> filter) { return ne

鉴于这种目的:

Foo foo = new Foo
{
    A = "a",
    B = "b",
    C = "c",
    D = "d"
};
如何仅序列化和反序列化某些属性(例如A和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" }
}
有什么想法吗

此外,是否有更好的或现有的替代方案

编辑:

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

编辑2:


任何序列化解决方案(JSON、XML、Binary、Yaml等)都很好。

有一些属性可以应用于控制序列化的类和/或属性

非常简单--只需使用
[ScriptIgnore]
属性来修饰您希望忽略的方法。

那么
[NonSerialized()]
属性标记呢

    class Foo  
    {
        field A;

        [NonSerialized()]
        field B;

        [NonSerialized()]
        field C;

        field D;  
    }

在过去,我曾经用Javascript序列化程序做过类似的事情。在我的例子中,我只想序列化包含值的对象中可为null的属性。为此,我使用反射,检查属性的值,并将属性添加到字典中

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;
}
公共静态字典CollectFilled属性(对象实例)
{
Dictionary filledProperties=new Dictionary();
对象数据=null;
PropertyInfo[]properties=instance.GetType().GetProperties();
foreach(属性中的PropertyInfo属性)
{
data=property.GetValue(实例,null);
if(IsNullable(property.PropertyType)&&data==null)
{
//忽略不带值的可为空字段,即(仍然为空)。
继续;
}
//他有数据。
Filled属性[property.Name]=数据;
}
返回filledProperties;
}
公共静态bool可为空(类型checkType)
{
if(checkType.IsGenericType&&checkType.GetGenericTypeDefinition()==typeof(可为空))
{
//我们是一个可空类型-yipee。
返回true;
}
返回false;
}

然后,您将字典和bob的叔叔传递给他们,而不是序列化原始对象。

我希望它更具动态性。所以我可以序列化A,B或C,D。然后你从错误的角度看这个问题——本机序列化是关于序列化对象的。最好的办法可能是创建两个对象——一个用于A和B,一个用于C和D,然后根据需要对其中任何一个进行序列化。这对二进制序列化有效。给出的示例是Java脚本序列化。我不确定它是否适用于这种类型。JavaScriptSerializer的等效属性是[ScriptIgnore()]。
    class Foo  
    {
        field A;

        [NonSerialized()]
        field B;

        [NonSerialized()]
        field C;

        field D;  
    }
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;
}