Как остановить элемент Batching из выполнения партии, когда есть нулевые элементы?

Выполните это с помощью msbuild:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Main" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemGroup>
    <Colors Include="Blue">
      <Shade>Dark</Shade>
    </Colors>
  </ItemGroup>

  <Target Name="Main">
    <Message Text="Color: %(Colors.Shade) %(Colors.Identity)"/>
  </Target>

</Project>

И он выводит:

Color: Dark Blue

Все хорошо, и хорошо, но удалите цвет и используйте это:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Main" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemGroup>
  </ItemGroup>

  <Target Name="Main">
    <Message Text="Color: %(Colors.Shade) %(Colors.Identity)"/>
  </Target>

</Project>

И он выводит:

Color:

Почему выполняется одна партия задачи Message, когда в группе нет элементов? Я бы ожидал, что для нулевых элементов партия будет выполнять нулевое время, и я не увижу "Цвет:", а затем ничего не выводит.

Я делаю что-то неправильно или есть обходное решение для этого?

Спасибо.


Обновление: Я нашел, что вы можете сделать:

<Message Condition="'@(Colors)'!=''" Text="Color: %(Colors.Shade) %(Colors.Identity)"/>

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

Ответы

Ответ 1

Мои 2 цента:

В вашей Задаче Сообщения есть информация из Пакетной и статической информации ("Цвета:"). Я думаю, что MsBuild печатает статическую информацию, а затем группирует значения вашего элемента цветов. Проблема в том, что у вас нет данных в вашей коллекции (они даже не объявлены), я предполагаю, что MsBuild интерпретирует это как пустой список, который, когда вы пытаетесь его распечатать, печатает пустую строку ''.

Если вы удалите статический контент ("Цвета:" и пробел перед идентификатором), у вас ничего не будет отображаться.

Решение для печати с пакетной обработкой, только если коллекция элементов не пуста, будет:

  1. Проверьте, пуста ли коллекция

    <Message Condition="'@(Colors)'!=''" Text="Color: %(Colors.Shade) %(Colors.Identity)"/>
    
  2. Используйте преобразования MSBuild

    <Message Text="@(Colors->'Color : %(Shade) %(Identity)')"/>
    

Ответ 2

Просто хотел добавить альтернативное решение для этого. Если вы можете изменить свою доработку до целевого пакета, вместо пакетной обработки задач, вы можете добавить свой оператор Condition в Target.

Я добавил целевую партию здесь:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Main" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemGroup>
  </ItemGroup>

  <Target Name="Main" Outputs="%(Colors.Identity)">
    <Message Text="Color: %(Colors.Shade) %(Colors.Identity)"/>
  </Target>

</Project>

... и это можно условно сделать только для выполнения, если что-то существует в группе элементов Colors:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Main" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemGroup>
  </ItemGroup>

  <Target Condition="'@(Colors)'!=''" Name="Main" Outputs="%(Colors.Identity)">
    <Message Text="Color: %(Colors.Shade) %(Colors.Identity)"/>
  </Target>

</Project>