区别不删除重复的项目?

时间:2012-06-29 15:44:23

标签: c# linq c#-4.0

我尝试了linq删除重复的项目:

   var MyItems = (from b in this.result
               select new Item{ Name = b.Name, ID = b.ID }).Distinct();

我检查了结果,没有删除重复的项目。 如何解决这个问题?

7 个答案:

答案 0 :(得分:5)

默认情况下,Distinct()使用EqualityComparer<T>.Default,其中包含以下规则:

  

默认的相等比较器Default用于比较实现IEquatable泛型接口的类型的值。要比较自定义数据类型,您需要实现此接口并为该类型提供自己的GetHashCode和Equals方法。

在您的情况下,这意味着Item需要实施IEquatable<Item>

或者,您可以使用直接带有IEqualityComparer<T>的{​​{3}}。

答案 1 :(得分:2)

您可以传递Distinct()一个比较器对象:

var MyItems = (from b in this.result
           select new Item{ Name = b.Name, ID = b.ID }).Distinct(new ItemComparer());

以下是自定义比较器类的示例

// Custom comparer for the Item class
class ItemComparer: IEqualityComparer<Product>
{
    // Items are equal if their names and IDs are equal.
    public bool Equals(Item x, Item y)
    {

        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

    //Check whether the items' properties are equal.
    return x.ID == y.ID && x.Name == y.Name;
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(Item item)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(item, null)) return 0;

        //Get hash code for the Name field if it is not null.
        int hashItemName = item.Name == null ? 0 : item.Name.GetHashCode();

        //Get hash code for the ID field.
        int hashItemID = item.ID.GetHashCode();

        //Calculate the hash code for the item.
        return hashItemName ^ hashItemID;
    }

}

答案 2 :(得分:1)

Regular Distinct()使用默认的相等比较器返回集合中的元素。

您可以使用自定义comparer

// modified example from docs, not tested
class MyComparer : IEqualityComparer<Item>
{
    // Items are equal if their ids are equal.
    public bool Equals(Item x, Item y)
    {

        // Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        // Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the items properties are equal.
        return x.ID == y.ID;
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(Product product)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(item, null)) return 0;

        //Get hash code for the ID field.
        int hashProductId = product.ID.GetHashCode();

        return hashProductId;
    }

}

var myItems = (from b in this.result
               select new Item{ Name = b.Name, ID = b.ID }).Distinct(new MyComparer());

答案 3 :(得分:1)

当您比较对象而不是基元时,您将不得不做一些工作来定义Distinct的含义。

查看包含Distinct的{​​{1}}覆盖: http://msdn.microsoft.com/en-us/library/bb338049.aspx

答案 4 :(得分:1)

由于我不知道你之后如何使用Items,我在这里赌博。

如果真的只需要ID-Name对,你可以使用匿名类型并免费获得比较:

var MyItems = (from b in this.result
               select new { b.Name, b.ID }).Distinct();

在此之后(并再次假设所需的全部是名称ID对),结果对象将具有您需要的属性:

foreach(var item in MyItems)
    Console.WriteLine("{0} -> {1}", item.ID, item.Name);

C# Anonymous Types上引用MSDN:

  

因为匿名类型上的Equals和GetHashCode方法是根据属性的Equals和GetHashcode方法定义的,所以同一匿名类型的两个实例只有在它们的所有属性相等时才相等。

答案 5 :(得分:1)

Enumerable.Distinct方法(IEnumerable)通过使用默认的相等比较器来比较值,从序列中返回不同的元素。

请检查一下: https://msdn.microsoft.com/en-us/library/bb348436.aspx

答案 6 :(得分:-4)

您需要向列表添加新项目,使用foreach考试:

foreach(var _item in result.Distinct()){
//Code here
}

好的:))