使用PropertyInfo []作为映射将对象序列化为xml

时间:2012-01-24 20:03:28

标签: c# serialization reflection

我正在尝试编写一个通用方法来序列化从我的ITable接口继承的对象。我还想有一个PropertyInfo []参数,我可以在其中指定需要与对象序列化的属性。那些不存在的人将被忽略。有没有办法告诉XmlSerialize只序列化列出的那些属性?

方法签名:

public static string SerializeToXml<T>(T obj, PropertyInfo[] fields = null) where T : ITable

如果fields为null,则自动获取所有字段。

if (fields == null)
{
    Type type = typeof(T);
    fields = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
}

2 个答案:

答案 0 :(得分:1)

通常情况下,您可以使用属性执行此操作,具体而言,您可以将the [XmlIgnore] attribute添加到您不想序列化的属性中(注意这是您想要的另一种方式)。

但是既然你想在运行时这样做,你可以使用the XmlAttributeOverrides class来猜测它,在运行时覆盖属性。

所以,这样的事情应该有效:

public static string SerializeToXml<T>(T obj, PropertyInfo[] fields = null)
    where T : ITable
{
    Type type = typeof(T);

    IEnumerable<PropertyInfo> ignoredProperties;

    if (fields == null)
        ignoredProperties = Enumerable.Empty<PropertyInfo>();
    else
        ignoredProperties = type.GetProperties(
            BindingFlags.Public | BindingFlags.Instance)
            .Except(fields);

    var ignoredAttrs = new XmlAttributes { XmlIgnore = true };

    var attrOverrides = new XmlAttributeOverrides();

    foreach (var ignoredProperty in ignoredProperties)
        attrOverrides.Add(type, ignoredProperty.Name, ignoredAttrs);

    var serializer = new XmlSerializer(type, attrOverrides);

    using (var writer = new StringWriter())
    {
        serializer.Serialize(writer, obj);
        return writer.ToString();
    }
}

在一个不相关的说明中,我认为命名包含属性fields的参数非常容易混淆。

答案 1 :(得分:0)

对于每个字段,声明一个属性,例如:

public bool ShouldSerializeX()
{
    return X != 0;
}

循环遍历字段时,将其属性设置为true或false,具体取决于是否要序列化它。

举例来说,如果Address中没有字段PropertyInfo,请将属性ShouldSerializeAddress设置为false,XmlSerializer应忽略它。

Check this answer for more info