Tuve una buena búsqueda en línea y no pude encontrar ninguna forma de hacerlo. Si alguien conoce una forma integrada y limpia, házmelo saber. Mientras tanto, escribí una tarea simple para hacer el trabajo. El uso es el siguiente:
<NormalizeByMetadata Items="@(ItemsToNormalize)" MetadataName="Filename">
<Output TaskParameter="NormalizedItems" ItemName="MyNormalizedItems"/>
</NormalizeByMetadata>
Después de la tarea anterior se ha ejecutado, MyNormalizedItems
contendrá sólo aquellos elementos de ItemsToNormalize
que tienen un valor único para los Filename
metadatos. Si dos o más elementos tienen el mismo valor para sus metadatos Filename
, la primera coincidencia se incluirá en la salida.
El código para la tarea de MSBuild es:
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();
}
}
}
Suena útil, gracias. Lo intentaré la próxima vez que lo necesite. –