我正在尝试编写一个通用方法来序列化从ITable接口继承的对象。我还想要一个PropertyInfo[]参数,在这里我可以指定需要与对象序列化的属性。那些不存在的将被忽略。是否有方法告诉XmlSerialize只序列化列出的属性?
方法签名:
public static string SerializeToXml<T>(T obj, PropertyInfo[] fields = null) where T : ITable
如果字段为空,则自动抓取所有字段。
if (fields == null)
{
Type type = typeof(T);
fields = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
}
通常,您会使用属性来完成此操作,特别是,您可以将[XmlIgnore]
属性添加到不想序列化的属性中(请注意,这与您想要的相反)。
但是,由于您希望在运行时执行此操作,您可以使用XmlAttributeOverrides
类在运行时覆盖属性。
所以,像这样的东西应该起作用:
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
的参数是非常令人困惑的。
对于每个字段,声明一个属性,例如:
public bool ShouldSerializeX()
{
return X != 0;
}
在字段中循环时,根据是否要序列化字段,将其属性设置为true或false。
例如,如果PropertyInfo
中没有字段Address
,请将属性ShouldSerializeAddress
设置为false,XmlSerializer应忽略它。
查看此答案以了解更多信息。