Это возможно при использовании инфраструктуры по умолчанию, используя свойства, которые возвращают объект типа XmlComment
, и помечая эти свойства [XmlAnyElement("SomeUniquePropertyName")]
.
т.е. если вы добавите свойство к 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>
Примечания:
Метод расширения XmlCommentExtensions.GetXmlCommentAttribute(this Type type, string memberName)
предполагает, что свойство комментария будет иметь имя xxxXmlComment
, где xxx
- это "реальное" свойство. Если это так, он может автоматически определить имя недвижимости, пометив входящий атрибут memberName
CallerMemberNameAttribute
. Это можно изменить вручную, передав реальное имя.
Как только тип и имя члена известны, метод расширения ищет соответствующий комментарий путем поиска атрибута [XmlComment]
, примененного к свойству. Это может быть заменено кэшированным поиском в отдельный файл документации.
Хотя по-прежнему необходимо добавлять свойства xxxXmlComment
для каждого свойства, которое может быть прокомментировано, это, вероятно, будет менее обременительным, чем непосредственная реализация IXmlSerializable
, что довольно сложно, может привести к ошибкам при десериализации и может потребовать вложенной сериализации сложных дочерних свойств.
Чтобы гарантировать, что каждый комментарий предшествует связанному с ним элементу, см. Управление порядком сериализации в C # .
Для XmlSerializer
для сериализации свойства у него должны быть как геттер, так и сеттер. Таким образом я дал комментарию свойства сеттеров, которые ничего не делают.
Рабочая .Net скрипка .