使用项函数

任务和目标中的代码可以调用项函数来获取项目中各项的相关信息(MSBuild 4.0 及更高版本)。 这些函数简化不同项的获取过程,并且比循环遍历项的速度更快。

字符串项函数

可以在 .NET Framework 中使用字符串方法和属性对任何项值进行操作。 对于 String 方法,指定方法名称。 对于 String 属性,请在“get_”之后指定属性名。

对于具有多个字符串的项,字符串方法或属性会对每个字符串运行。

下面的示例显示如何使用这些字符串项函数。

<ItemGroup>
    <theItem Include="andromeda;tadpole;cartwheel" />
</ItemGroup>

<Target Name = "go">
    <Message Text="IndexOf  @(theItem->IndexOf('r'))" />
    <Message Text="Replace  @(theItem->Replace('tadpole', 'pinwheel'))" />
    <Message Text="Length   @(theItem->get_Length())" />
    <Message Text="Chars    @(theItem->get_Chars(2))" />
</Target>

  <!--
  Output:
    IndexOf  3;-1;2
    Replace  andromeda;pinwheel;cartwheel
    Length   9;7;9
    Chars    d;d;r
  -->

内部项函数

下表列出了可用于各项的内部函数。

函数 示例 说明
Combine @(MyItems->Combine('path')) 返回一组新的项,其中包含追加到所有输入项的给定相对路径。
Count @(MyItems->Count()) 返回项计数。
DirectoryName @(MyItems->DirectoryName()) 返回每个项的 Path.DirectoryName 等效项。
Distinct @(MyItems->Distinct()) 返回具有不同 Include 值的项。 忽略元数据。 比较不区分大小写。
DistinctWithCase @(MyItems->DistinctWithCase()) 返回具有不同 itemspec 值的项。 忽略元数据。 比较是区分大小写的。
Exists @(MyItems->Exists()) 将一组项筛选为磁盘上实际存在的项。
GetPathsOfAllDirectoriesAbove @(MyItems->GetPathsOfAllFilesAbove()) 给定一组项,返回表示所有上级目录的项。 不保证顺序。
Reverse @(MyItems->Reverse()) 按相反顺序返回项。
AnyHaveMetadataValue @(MyItems->AnyHaveMetadataValue("MetadataName", "MetadataValue")) 返回 boolean,指示是否有任何项具有给定的元数据名和值。 比较不区分大小写。
ClearMetadata @(MyItems->ClearMetadata()) 返回清除了元数据的项。 仅保留 itemspec
HasMetadata @(MyItems->HasMetadata("MetadataName")) 返回具有给定元数据名的项。 比较不区分大小写。
Metadata @(MyItems->Metadata("MetadataName")) 返回具有元数据名的元数据的值。 返回的项具有与源值相同的元数据。
WithMetadataValue @(MyItems->WithMetadataValue("MetadataName", "MetadataValue")) 返回具有给定元数据名和值的项。 比较不区分大小写。

注意

Exists 也可以在其他上下文中使用;在 MSBuild 条件中,例如 Condition="Exists('path')";或在静态属性函数中,例如 $([System.IO.File]::Exists("path"))

下面的示例显示如何使用内部项函数。

<ItemGroup>
    <TheItem Include="first">
        <Plant>geranium</Plant>
    </TheItem>
    <TheItem Include="second">
        <Plant>algae</Plant>
    </TheItem>
    <TheItem Include="third">
        <Plant>geranium</Plant>
    </TheItem>
</ItemGroup>

<Target Name="go">
    <Message Text="MetaData:    @(TheItem->Metadata('Plant'))" />
    <Message Text="HasMetadata: @(theItem->HasMetadata('Plant'))" />
    <Message Text="WithMetadataValue: @(TheItem->WithMetadataValue('Plant', 'geranium'))" />
    <Message Text=" " />
    <Message Text="Count:   @(theItem->Count())" />
    <Message Text="Reverse: @(theItem->Reverse())" />
</Target>

  <!--
  Output:
    MetaData:    geranium;algae;geranium
    HasMetadata: first;second;third
    WithMetadataValue: first;third

    Count:   3
    Reverse: third;second;first
  -->

使用元数据项函数时检测重复项

Metadata 项函数保留了源项的原始元数据。 在考虑返回的项是否为重复项时,这会产生一些影响。 要控制如何处理重复项,可以使用 KeepDuplicates 属性。 如果你不需要元数据,还可以通过添加 RemoveMetadata 来删除元数据,在这种情况下,检测重复项时就只会考虑值本身。

  <Target Name="MetadataToItem">
    <ItemGroup>
      <Sample Include="AAA" SomeItems="1;2;3" />
      <Sample Include="BBB" SomeItems="3;4;5" />
    </ItemGroup>

    <ItemGroup>
      <AllSomeItems Include="@(Sample->Metadata('SomeItems'))" KeepDuplicates="false" />
    </ItemGroup>
    <Message Text="AllSomeItems is @(AllSomeItems)" />
  </Target>

输出如下所示:

MetadataToItem:
  AllSomeItems is 1;2;3;3;4;5

对代码的以下更改会导致成功检测到并删除重复项值:

    <ItemGroup>
      <AllSomeItems Include="@(Sample->Metadata('SomeItems'))" KeepDuplicates="false" RemoveMetadata="SomeItems" />
    </ItemGroup>

MSBuild 条件函数

函数 HasTrailingSlash 不是项函数。 它可与 Condition 属性一起使用。 请参阅 MSBuild 条件

还可以使用属性对项列表执行操作,例如对项元数据进行筛选。 有关详细信息,请参阅