Сравнение свойств и элементов

Свойства и элементы MSBuild используются для передачи информации в задачи, оценки условий и хранения значений, на которые можно ссылаться в файле проекта.

  • Свойства — это пары "имя-значение". Дополнительные сведения см. в разделе свойства MSBuild.

  • Элементы — это объекты, которые обычно представляют файлы. Объекты элементов могут иметь связанные коллекции метаданных. Метаданные — это пары "имя-значение". Дополнительные сведения см. в разделе Элементы.

Скалярные и векторы

Так как свойства MSBuild — это пары "имя-значение", имеющие только одно строковое значение, они часто описываются как скалярные. Поскольку типы элементов MSBuild являются списками элементов, они часто описываются как вектор. Однако на практике свойства могут представлять несколько значений, а типы элементов могут иметь ноль или один элемент.

Внедрение целевых зависимостей

Чтобы узнать, как свойства могут представлять несколько значений, рассмотрим распространенный шаблон использования для добавления целевого объекта в список созданных целевых объектов. Как правило, этот список представлен значением свойства с именами целевых объектов, разделенными точкой с запятой.

<PropertyGroup>
    <BuildDependsOn>
        BeforeBuild;
        CoreBuild;
        AfterBuild
    </BuildDependsOn>
</PropertyGroup>

Свойство BuildDependsOn обычно используется в качестве аргумента целевого DependsOnTargets атрибута, эффективно преобразуя его в список элементов. Это свойство можно переопределить, чтобы добавить целевой объект или изменить порядок выполнения целевого объекта. Например

<PropertyGroup>
    <BuildDependsOn>
        $(BuildDependsOn);
        CustomBuild;
    </BuildDependsOn>
</PropertyGroup>

добавляет целевой объект CustomBuild в целевой список, предоставляя BuildDependsOn значение BeforeBuild;CoreBuild;AfterBuild;CustomBuild.

Начиная с MSBuild 4.0, внедрение целевых зависимостей устарело. AfterTargets BeforeTargets Вместо этого используйте атрибуты. Дополнительные сведения см. в разделе "Целевой порядок сборки".

Преобразования между строками и списками элементов

MSBuild выполняет преобразования в типы элементов и строковые значения и из них по мере необходимости. Чтобы узнать, как список элементов может стать строковым значением, рассмотрим, что происходит при использовании типа элемента в качестве значения свойства MSBuild:

<ItemGroup>
    <OutputDir Include="KeyFiles\;Certificates\" />
</ItemGroup>
<PropertyGroup>
    <OutputDirList>@(OutputDir)</OutputDirList>
</PropertyGroup>

Тип элемента OutputDir имеет Include атрибут со значением KeyFiles\; Сертификаты\". MSBuild анализирует эту строку на два элемента: KeyFiles\ и Certificates\. Если тип элемента OutputDir используется в качестве значения свойства OutputDirList, MSBuild преобразует или "неструктурирует" тип элемента в строку с запятой "KeyFiles\; Сертификаты\".

Свойства и элементы в задачах

Свойства и элементы используются в качестве входных и выходных данных для задач MSBuild. Дополнительные сведения см. в разделе Задачи.

Свойства передаются задачам в виде атрибутов. В задаче свойство MSBuild представлено типом свойства, значение которого можно преобразовать в строку и из нее. Поддерживаемые типы свойств включают bool, char, , DateTimeDecimal, Double, intstringи любой тип, который ChangeType может обрабатывать.

Элементы передаются задачам в виде ITaskItem объектов. В задаче ItemSpec представляет значение элемента и GetMetadata извлекает его метаданные.

Список элементов типа элемента можно передать в виде массива ITaskItem объектов. Элементы можно удалить из списка элементов в целевом объекте с помощью атрибута Remove . Так как элементы могут быть удалены из списка элементов, возможно, что тип элемента имеет ноль элементов. Если список элементов передается в задачу, код в задаче должен проверить эту возможность.

Порядок оценки свойств и элементов

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

  • Свойства определяются и изменяются в порядке их отображения.

  • Определения элементов определяются и изменяются в порядке их отображения.

  • Элементы определяются и изменяются в порядке их отображения.

На этапе выполнения сборки свойства и элементы, определенные в целевых объектах, оцениваются вместе на одном этапе в порядке их отображения.

Однако это не полная история. При определении свойства, определения элемента или элемента его значение вычисляется. Средство оценки выражений расширяет строку, указывающую значение. Расширение строки зависит от этапа сборки. Ниже приведен более подробный порядок оценки свойств и элементов:

  • На этапе оценки сборки:

    • Свойства определяются и изменяются в порядке их отображения. Выполняются функции свойств. Значения свойств в форме $(PropertyName) расширяются в выражениях. Значение свойства присваивается расширенному выражению.

    • Определения элементов определяются и изменяются в порядке их отображения. Функции свойств уже развернуты в выражениях. Значения метаданных задаются для развернутых выражений.

    • Типы элементов определяются и изменяются в порядке их отображения. Значения элементов в форме @(ItemType) развернуты. Преобразования элементов также расширяются. Функции и значения свойств уже развернуты в выражениях. Для развернутых выражений заданы значения списка элементов и метаданных.

  • На этапе выполнения сборки:

    • Свойства и элементы, определенные в целевых объектах, оцениваются вместе в том порядке, в котором они отображаются. Функции свойств выполняются, а значения свойств расширяются в выражениях. Также расширяются значения элементов и преобразования элементов. Значения свойств, значения типов элементов и значения метаданных задаются для развернутых выражений.

Тонкие эффекты порядка оценки

На этапе оценки сборки оценка свойств предшествует оценке элементов. Тем не менее свойства могут иметь значения, которые, как представляется, зависят от значений элементов. Рассмотрим следующий сценарий.

<ItemGroup>
    <KeyFile Include="KeyFile.cs">
        <Version>1.0.0.3</Version>
    </KeyFile>
</ItemGroup>
<PropertyGroup>
    <KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
</PropertyGroup>
<Target Name="AfterBuild">
    <Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>

При выполнении задачи "Сообщение" отображается следующее сообщение:

KeyFileVersion: 1.0.0.3

Это связано с тем, что значение KeyFileVersion на самом деле является строкой "@(KeyFile->"%(версия))". Преобразования элементов и элементов не были развернуты при первом определении свойства, поэтому KeyFileVersion свойство было назначено значение нераспределенной строки.

На этапе выполнения сборки при обработке задачи "Сообщение" MSBuild расширяет строку "@(KeyFile->"%(версия))" для получения "1.0.0.3".

Обратите внимание, что одно и то же сообщение будет отображаться, даже если группы свойств и элементов были изменены в порядке.

В качестве второго примера рассмотрим, что может произойти, когда группы свойств и элементов находятся в целевых объектах:

<Target Name="AfterBuild">
    <PropertyGroup>
        <KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
    </PropertyGroup>
    <ItemGroup>
        <KeyFile Include="KeyFile.cs">
            <Version>1.0.0.3</Version>
        </KeyFile>
    </ItemGroup>
    <Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>

Задача "Сообщение" отображает следующее сообщение:

KeyFileVersion:

Это связано с тем, что во время этапа выполнения сборки группы свойств и элементов, определенные в целевых объектах, оцениваются сверху вниз одновременно. Когда KeyFileVersion определено, KeyFile неизвестно. Поэтому преобразование элемента расширяется до пустой строки.

В этом случае отмена порядка групп свойств и элементов восстанавливает исходное сообщение:

<Target Name="AfterBuild">
    <ItemGroup>
        <KeyFile Include="KeyFile.cs">
            <Version>1.0.0.3</Version>
        </KeyFile>
    </ItemGroup>
    <PropertyGroup>
        <KeyFileVersion>@(KeyFile->'%(Version)')</KeyFileVersion>
    </PropertyGroup>
    <Message Text="KeyFileVersion: $(KeyFileVersion)" />
</Target>

Для параметра задано значение KeyFileVersion "1.0.0.3", а не "@(KeyFile->"%(версия)). Задача "Сообщение" отображает следующее сообщение:

KeyFileVersion: 1.0.0.3