У меня был хороший поиск в Интернете, и я не мог найти способ сделать это. Если кто-нибудь знает чистый встроенный способ, пожалуйста, дайте мне знать. Тем временем я написал простое задание, чтобы выполнить работу. Использование выглядит так:
<NormalizeByMetadata Items="@(ItemsToNormalize)" MetadataName="Filename">
<Output TaskParameter="NormalizedItems" ItemName="MyNormalizedItems"/>
</NormalizeByMetadata>
После выполнения вышеуказанной задачи MyNormalizedItems
будет содержать только те элементы из ItemsToNormalize
, которые имеют уникальное значение для метаданных Filename
. Если два или более элемента имеют одинаковое значение для своих метаданных Filename
, первое совпадение будет включено в выходные данные.
Код для задачи MSBuild:
public class NormalizeByMetadata : Task
{
[Required]
public ITaskItem[] Items
{
get;
set;
}
[Required]
public string MetadataName
{
get;
set;
}
[Output]
public ITaskItem[] NormalizedItems
{
get;
private set;
}
public override bool Execute()
{
NormalizedItems = Items.Distinct(new ItemEqualityComparer(MetadataName)).ToArray();
return true;
}
private sealed class ItemEqualityComparer : IEqualityComparer<ITaskItem>
{
private readonly string _metadataName;
public ItemEqualityComparer(string metadataName)
{
Debug.Assert(metadataName != null);
_metadataName = metadataName;
}
public bool Equals(ITaskItem x, ITaskItem y)
{
if (x == null || y == null)
{
return x == y;
}
var xMetadata = x.GetMetadata(_metadataName);
var yMetadata = y.GetMetadata(_metadataName);
return string.Equals(xMetadata, yMetadata);
}
public int GetHashCode(ITaskItem obj)
{
if (obj == null)
{
return 0;
}
var objMetadata = obj.GetMetadata(_metadataName);
return objMetadata.GetHashCode();
}
}
}