通过将MetadataTypeAttribute放在班上,您可以使用元数据“好友班级”。如果它不是已经生成的类,我会让它生成partial,然后创建另一个partial类并将MetadataType Attribute添加到该类。然后,如果您从XSD重新生成类,但它不是部分,编译器会发出抱怨,并且您会记得使其部分。
我不太喜欢“伙伴类”,因为属性重复,并不真正干,但它可能是您正在寻找的解决方案。对于元数据类,通常是有关验证属性的一个简单概述 - 但它适用于任何属性,你可以找到MS here
你可以看到回答https://stackoverflow.com/a/26724847/1798889如何使XmlSerializer的了解一个哥们类。
更新
现在我想想这个,如果你不想使用好友类,你可以建立一个流畅的API来配置XML序列化。
我们将保留来自XMLSerializer with buddy class question的CustomAttributeProvider类,而是创建一个XmlSerializerConfigurator类。
public class XmlSerializerConfigurator<T>
{
private readonly XmlAttributeOverrides _xmlAttributeOverrides;
public XmlSerializerConfigurator(XmlAttributeOverrides xmlAttributeOverrides)
{
_xmlAttributeOverrides = xmlAttributeOverrides;
}
public XmlSerializerConfigurator() : this(new XmlAttributeOverrides())
{
}
/// <summary>
/// Adds attributes to properties or fields and strongly typed
/// </summary>
/// <typeparam name="TData"></typeparam>
/// <param name="property"></param>
/// <param name="xmlAttributes"></param>
/// <returns></returns>
public XmlSerializerConfigurator<T> AddPropertyOrFieldAttributes<TData>(Expression<Func<T, TData>> property,
params Attribute[] xmlAttributes)
{
var memberName = property.GetName();
_xmlAttributeOverrides.Add(typeof (T), memberName,
new XmlAttributes(new CustomAttributeProvider(xmlAttributes)));
return this;
}
/// <summary>
/// Adds class level attributes
/// </summary>
/// <param name="xmlAttributes"></param>
/// <returns></returns>
public XmlSerializerConfigurator<T> AddClassLevelAttributes(params Attribute[] xmlAttributes)
{
_xmlAttributeOverrides.Add(typeof(T), new XmlAttributes(new CustomAttributeProvider(xmlAttributes)));
return this;
}
/// <summary>
/// Creates an XmlSerializerConfigurator that is tied to the main one
/// </summary>
/// <typeparam name="K"></typeparam>
/// <returns></returns>
public XmlSerializerConfigurator<K> ChildClassConfigurator<K>()
{
// passes in own XmlAttributeOverrides and since object reference it will fill the same object
return new XmlSerializerConfigurator<K>(_xmlAttributeOverrides);
}
/// <summary>
/// Returns back an XmlSerializer with this configuration
/// </summary>
/// <returns></returns>
public XmlSerializer GetSerializer()
{
return new XmlSerializer(typeof(T), _xmlAttributeOverrides);
}
}
这个类将允许你配置哪些属性在Serializer的什么类/属性上,而不是依赖于好友类。当类有另一个类时,我们需要ChildClassAttributes,因为它的属性允许配置该类。
此外,我使用一种扩展方法,从称为GetName的表达式返回属性或字段。
public static string GetName<TEntity, TData>(this Expression<Func<TEntity, TData>> field)
{
var name = "";
if (field.Body is MemberExpression)
{
var body = field.Body as MemberExpression;
var ebody = body.Expression as MemberExpression;
if (ebody != null)
{
name = ebody.Member.Name + ".";
}
name = name + body.Member.Name;
}
else if (field.Body is UnaryExpression)
{
var ubody = field.Body as UnaryExpression;
var body = ubody.Operand as MemberExpression;
var ebody = body.Expression as MemberExpression;
if (ebody != null)
{
name = ebody.Member.Name + ".";
}
name = name + body.Member.Name;
}
else if (field.Body is ConstantExpression)
{
var cbody = field.Body as ConstantExpression;
name = cbody.Value.ToString();
}
else
{
throw new InvalidOperationException(String.Format("{0} not supported.", field));
}
return name;
}
现在你可以使用/配置它这样
var xmlConfiguration = new XmlSerializerConfigurator<Group>();
xmlConfiguration.AddPropertyOrFieldAttributes(x => x.Employees, new XmlArrayItemAttribute(typeof (Employee)),
new XmlArrayItemAttribute(typeof (Manager)));
xmlConfiguration.AddClassLevelAttributes(new XmlRootAttribute("GroupName"));
var childConfiguration = xmlConfiguration.ChildClassConfigurator<Employee>();
childConfiguration.AddPropertyOrFieldAttributes(x => x.FullName, new XmlElementAttribute("Name"));
var xmlSerializer = xmlConfiguration.GetSerializer();
现在所有的属性和字段是强类型和一哥们类不重复。
谢谢男人,我欣赏它! – user1158555 2014-11-04 12:31:39