使用LINQ选择唯一项目

时间:2010-09-16 09:52:16

标签: c# linq distinct

当我使用以下代码时,我会多次获得相同的项目。

XElement neededFiles = new XElement("needed",
    from o in _9nFiles.Elements()
    join t in addedToSitePull.Elements()
         on o.Value equals
         t.Value
    where o.Value == t.Value
    select new XElement("pic", o.Value));

我想只获得独特的物品。我看到了一个Stack Overflow帖子, How can I do SELECT UNIQUE with LINQ? ,它使用了它,我试图实现它,但是这个改变没有任何影响。

代码:

XElement neededFiles = new XElement("needed",
(from o in _9nFiles.Elements()
join t in addedToSitePull.Elements()
on o.Value equals
 t.Value
 where o.Value == t.Value
select new XElement("pic", o.Value)).Distinct() );

3 个答案:

答案 0 :(得分:7)

我认为这不起作用的原因是因为XElement.Equals使用简单的引用相等性检查而不是比较两个项的Value属性。如果要比较值,可以将其更改为:

_9nfiles.Elements()
    .Join(addedToSitePull, o => o.Value, t => t.Value, (o, t) => o.Value)
    .Distinct()
    .Select(val => new XElement("pic", val));

您还可以创建自己的IEqualityComparer<T>,用于比较两个XElement的值。请注意,这假设所有值都是非空的:

public class XElementValueEqualityComparer : IEqualityComparer<XElement>
{
    public bool Equals(XElement x, XElement y)
    {
        return x.Value.Equals(y.Value);
    }

    public int GetHashCode(XElement x)
    {
        return x.Value.GetHashCode();
    }
}

然后,您可以使用Distinct替换现有的Distinct(new XElementValueEqualityComparer())来电。

答案 1 :(得分:4)

区别不起作用,因为XElements是通过引用而不是按值进行比较。 解决方案是使用Distinct的另一个重载 - Distinct(IEqualityComparer);

您需要实现IEqualityComparer,例如如下:

class XElementEqualityComparer : IEqualityComparer<XElement>
    {
        #region IEqualityComparer<XElement> Members

        public bool Equals(XElement x, XElement y)
        {
            if (x == null ^ y == null)
                return false;

            if (x == null && y == null)
                return true;

            return x.Value == y.Value;
        }

        public int GetHashCode(XElement obj)
        {
            if (obj == null)
                return 0;

            return obj.Value.GetHashCode();
        }

        #endregion
    }

答案 2 :(得分:0)

这不是一个好的解决方案 - 但非常简单。

foreach (XElement  pic in neededFiles.Elements())
{
    unSyncedPictures.Add(pic.Value);
}
List<string> temp = new List<string>();
temp.AddRange(unSyncedPictures.Distinct());