通过使用返回类型对象的属性,可以使用默认基础结构来实现这一点XmlComment https://msdn.microsoft.com/en-us/library/system.xml.xmlcomment.aspx并将这些属性标记为[XmlAnyElement("SomeUniquePropertyName")] https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlanyelementattribute.aspx.
IE。如果您添加一个属性Foo
像这样:
public class Foo
{
[XmlAnyElement("VersionComment")]
public XmlComment VersionComment { get { return new XmlDocument().CreateComment("The application version, NOT the file version!"); } set { } }
public string Version { get; set; }
public string Name { get; set; }
}
将生成以下 XML:
<Foo>
<!--The application version, NOT the file version!-->
<Version>1.0</Version>
<Name>Bar</Name>
</Foo>
然而,问题所要求的不仅仅是这个,即某种在文档系统中查找评论的方法。以下通过使用扩展方法根据反映的注释属性名称查找文档来实现此目的:
public class Foo
{
[XmlAnyElement("VersionXmlComment")]
public XmlComment VersionXmlComment { get { return GetType().GetXmlComment(); } set { } }
[XmlComment("The application version, NOT the file version!")]
public string Version { get; set; }
[XmlAnyElement("NameXmlComment")]
public XmlComment NameXmlComment { get { return GetType().GetXmlComment(); } set { } }
[XmlComment("The application name, NOT the file name!")]
public string Name { get; set; }
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class XmlCommentAttribute : Attribute
{
public XmlCommentAttribute(string value)
{
this.Value = value;
}
public string Value { get; set; }
}
public static class XmlCommentExtensions
{
const string XmlCommentPropertyPostfix = "XmlComment";
static XmlCommentAttribute GetXmlCommentAttribute(this Type type, string memberName)
{
var member = type.GetProperty(memberName);
if (member == null)
return null;
var attr = member.GetCustomAttribute<XmlCommentAttribute>();
return attr;
}
public static XmlComment GetXmlComment(this Type type, [CallerMemberName] string memberName = "")
{
var attr = GetXmlCommentAttribute(type, memberName);
if (attr == null)
{
if (memberName.EndsWith(XmlCommentPropertyPostfix))
attr = GetXmlCommentAttribute(type, memberName.Substring(0, memberName.Length - XmlCommentPropertyPostfix.Length));
}
if (attr == null || string.IsNullOrEmpty(attr.Value))
return null;
return new XmlDocument().CreateComment(attr.Value);
}
}
为此生成以下 XML:
<Foo>
<!--The application version, NOT the file version!-->
<Version>1.0</Version>
<!--The application name, NOT the file name!-->
<Name>Bar</Name>
</Foo>
Notes:
扩展方法XmlCommentExtensions.GetXmlCommentAttribute(this Type type, string memberName)
假设评论属性将被命名xxxXmlComment
where xxx
是“真实”的财产。如果是这样,它可以通过标记传入的内容来自动确定真实的属性名称memberName
属性与CallerMemberNameAttribute https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute.aspx。可以通过传入真实姓名来手动覆盖此设置。
一旦知道类型和成员名称,扩展方法就会通过搜索[XmlComment]
应用于属性的属性。这可以替换为对单独文档文件的缓存查找。
虽然仍然需要添加xxxXmlComment
每个可能被注释的属性的属性,这可能比实施IXmlSerializable直接地 https://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly这是相当棘手的,可能会导致反序列化中的错误,并且可能需要复杂子属性的嵌套序列化。
要确保每个注释位于其关联元素之前,请参阅控制 C# 中的序列化顺序 https://stackoverflow.com/q/3373529.
For XmlSerializer
要序列化属性,它必须同时具有 getter 和 setter。因此,我给出了不执行任何操作的注释属性设置器。
Working .Net小提琴 https://dotnetfiddle.net/yjI8Z6.