Почему XML-генератор документации C# работает некорректно для COM-импортированных интерфейсов?

При использовании комментариев XML-документации в C# для создания XML-файла документации в VS2010 SP1 я заметил, что он не работает должным образом в одном конкретном случае: для членов интерфейса, импортированных из COM. > (методы и свойства).

Давайте возьмем этот файл C#, взяв в качестве примера некоторые типы из первичной сборки взаимодействия MS Word (которая, я думаю, широко известна большинству людей):

using Microsoft.Office.Interop.Word;
namespace TestProject
{
    /// <summary>
    /// Documentation test class. This documentation references a COM interface: <see cref="_Document"/>
    /// and a method in that interface: <see cref="_Document.Activate"/>, as well as a property
    /// <see cref="_Document.ActiveTheme"/>.
    /// </summary>
    public class DocumentedClass
    {
    }
}

Полученный файл документации .XML содержит следующее:

<member name="T:TestProject.DocumentedClass">
    <summary>
    Documentation test class. This documentation references a COM interface: <see cref="T:Microsoft.Office.Interop.Word._Document"/>
    and a method in that interface: <see cref="!:_Document.Activate"/>, as well as a property
    <see cref="!:_Document.ActiveTheme"/>.
    </summary>
</member>

Если вы внимательно посмотрите на сгенерированный фрагмент XML-файла, то увидите, что ссылка на COM-интерфейс разрешена (T:Microsoft.Office.Interop.Word._Document), но не разрешена для членов интерфейса (например, !:_Document.Activate).

Я попытался полностью квалифицировать элементы интерфейса в комментариях к документации следующим образом, но результат тот же:

namespace TestProject
{
    /// <summary>
    /// Documentation test class. This documentation references
    /// a COM interface: <see cref="Microsoft.Office.Interop.Word._Document"/>
    /// and a method in that interface: <see cref="Microsoft.Office.Interop.Word._Document.Activate"/>,
    /// as well as a property: <see cref="Microsoft.Office.Interop.Word._Document.ActiveTheme"/>.
    /// </summary>
    public class DocumentedClass2
    {
    }
}

Теперь странно то, что это, кажется, работает для COM-импортированных членов класса, например. эта документация:

using Microsoft.Office.Interop.Word;
namespace TestProject
{
    /// <summary>
    /// Now, let's reference a COM class <see cref="ParagraphFormatClass"/> and its member property
    /// <see cref="ParagraphFormatClass.Alignment"/>.
    /// </summary>
    public class DocumentedClass3
    {
    }
}

приводит к следующему фрагменту файла XML-документации:

<member name="T:TestProject.DocumentedClass3">
    <summary>
    Now, let's reference a COM class <see cref="T:Microsoft.Office.Interop.Word.ParagraphFormatClass"/> and its member
    <see cref="P:Microsoft.Office.Interop.Word.ParagraphFormatClass.Alignment"/>.
    </summary>
</member>

что совершенно верно, поскольку свойство класса COM правильно разрешается в P:Microsoft.Office.Interop.Word.ParagraphFormatClass.Alignment.

Это действительно происходит только для COM-импортированных интерфейсов, обычные члены интерфейса правильно ссылаются в результирующих XML-файлах документации. Не имеет значения, получен ли COM-импортированный интерфейс из PIA или вы сами импортируете библиотеку типов через tlbimp.exe.

У меня такой вопрос: есть ли причина такого поведения или это ошибка? Что я могу сделать, чтобы импортированные COM-члены интерфейса правильно ссылались в сгенерированных файлах XML-документации?


person petr k.    schedule 28.03.2012    source источник
comment
Зарегистрирована эта проблема в Microsoft Connect: connect.microsoft.com/VisualStudio/feedback/details/734928/   -  person petr k.    schedule 01.04.2012


Ответы (2)


Действительно интересная проблема. Я мог бы воспроизвести это, но для ParagraphFormatClass.Alignment это все еще неправильно для меня. Что еще интереснее, если вы действительно используете эти элементы в своем коде (в заданном методе), даже в блоке if (false) ссылки XML cref разрешаются правильно. Но, к сожалению, этот трюк работает только в методах, а не в классах. Поэтому я думаю, что у вас нет другого выбора, кроме как вручную ввести идентификаторы ссылок на элементы:

<see cref="M:Microsoft.Office.Interop.Word._Document.Activate"/>

<see cref="P:Microsoft.Office.Interop.Word._Document.ActiveTheme"/>
person Balazs Tihanyi    schedule 28.03.2012
comment
Да, я пытался ввести ссылку вручную. Единственная проблема в том, что я использую Resharper, и он, кажется, подчеркивает и жалуется на определенные ссылки, подобные этой. Интересно, что он не подчеркивает те недопустимые ссылки, которые в противном случае выводятся как предупреждение компилятора. Что-то неладное во всем этом.. :-) - person petr k.; 29.03.2012
comment
Как вы заставили его работать с ParagraphFormatClass.Alignment? Это может быть правильным решением... - person Balazs Tihanyi; 29.03.2012
comment
Образец в моем посте просто работает для меня. Если это не работает для вас, это может означать, что поведение не соответствует 100%. - person petr k.; 29.03.2012
comment
Не повезло мне. Это очень, очень странно. - person Balazs Tihanyi; 29.03.2012

Это приложение .NET 4.0? Если это так, это может быть вызвано тем, что компилятор использует динамические типы за кулисами. Если ваш проект содержит ссылку на Microsoft.CSharp, это указывает на возможность использования динамических типов. Если вы удалите ссылку и выполните сборку, вы получите ошибки компилятора о том, что он не может разрешить типы, необходимые для динамического кода, если это так. Выполнение этого в моих проектах надстроек помечает экземпляры, в которых я использую Document и несколько других типов, как требующие динамических типов связывания. Возможно, поэтому компилятор разрешает члены класса, но не интерфейсы. Для экземпляров, где используются динамические типы, они не будут разрешены до времени выполнения. Таким образом, компилятору нечего использовать для идентификатора члена XML-комментариев. Во всяком случае, это моя теория.

person EWoodruff    schedule 30.03.2012
comment
Я совершенно уверен, что динамическое разрешение здесь не проблема. Во-первых, это не приложение .NET 4 (но проблема возникает и в .NET 4). Во-вторых, это происходит даже при использовании COM-типов, которые не наследуются от IDispatch. Большинство типов, на которые я фактически пытаюсь ссылаться в моей реальной документации, относятся только к IUnknown. В-третьих, проблема также возникает с перечислениями (на которые ссылаются правильно) и их элементами (которые не разрешены). - person petr k.; 30.03.2012
comment
Что действительно интересно - как обнаружил Балаш в своем ответе, когда вы фактически используете члены в теле метода, их ссылки правильно разрешаются в файле XML. - person petr k.; 30.03.2012