Distinct()不调用equals方法

时间:2014-01-07 14:30:14

标签: c# silverlight windows-phone-8 windows-phone observablecollection

我已经实现了IEqualityComparer和IEquatable(两者都是为了确定),但是当我在集合上调用Distinct()方法时,它不会调用随附的方法。这是我在调用Distinct()时执行的代码。

ObservableCollection<GigViewModel> distinctGigs = new ObservableCollection<GigViewModel>(Gigs.Distinct<GigViewModel>());
return distinctGigs;

我想返回一个ObservableCollection,它不包含'Gigs'ObservableCollection中的任何双重对象。

我在GigViewModel类上实现了这样的接口:

public class GigViewModel : INotifyPropertyChanged, IEqualityComparer<GigViewModel>, IEquatable<GigViewModel>
{
    ....
}

并覆盖接口附带的方法,如下所示:

public bool Equals(GigViewModel x, GigViewModel y)
{          
    if (x.Artiest.Naam == y.Artiest.Naam)
    {
        return true;
    }
    else
    {
        return false;
    }
 }

 public int GetHashCode(GigViewModel obj)
 {
     return obj.Artiest.Naam.GetHashCode();
 }

 public bool Equals(GigViewModel other)
 {
     if (other.Artiest.Naam == this.Artiest.Naam)
     {
         return true;
     }
     else
     {
         return false;
     }
 }

感谢我得到的所有帮助。所以我创建了一个单独的类来实现IEqualityComparer并将它的实例传递给disctinct方法。但这些方法仍未触发。

EqualityComparer:

class GigViewModelComparer : IEqualityComparer<GigViewModel>
{
    public bool Equals(GigViewModel x, GigViewModel y)
    {

        if (x.Artiest.Naam == y.Artiest.Naam)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public int GetHashCode(GigViewModel obj)
    {
        return obj.Artiest.Naam.GetHashCode();
    }
}

Distinct()来电:

 GigViewModelComparer comp = new GigViewModelComparer();
 ObservableCollection<GigViewModel> distinctGigs = new ObservableCollection<GigViewModel>(Gigs.Distinct(comp));
 return distinctGigs;

EDIT2:

GetHashCode()方法被调用!实施新课程后。但该集合仍包含重复项。我有一个'Gigs'列表,其中包含一个'Artiest'(或Artist)对象。此Artist具有Naam属性,即String(Name)。

2 个答案:

答案 0 :(得分:7)

因此,您拥有与其进行比较的对象,同时实现IEquatableIEqualityComparer。这通常没有意义。 IEquatable是一种说明对象可以将自己与其他东西进行比较的方式。 IEqualityComparer是一种说法,可以比较两种不同的东西。你通常想做一个或另一个,而不是两者。

如果要实现IEquatable,那么该对象不仅需要具有相应签名的Equals方法,而且还需要覆盖GetHashCode才能实现合理的签名。给出了平等的定义。 您没有那样做。您创建了GetHashCode方法,该方法将对象作为参数,但这是用于IEqualityComparer的重载。使用IEquatableObject中定义的版本)时,您需要覆盖无参数版本。

如果要创建实现IEqualityComparer的类,则需要将比较器传递给Distinct方法。由于您已将对象定义为自己的比较器,因此您需要将此对象的某个实例作为第二个参数传递。当然,这并没有真正意义上的这种方式;所以如果你走这条路线,将IEqualityComparer的两个方法拉出到一个新类型中会更好,并为Distinct方法创建一个该类型的实例。如果您实际上将具有这些定义的对象作为比较器传递,它就可以正常工作。

答案 1 :(得分:1)

在MSDN的advice之后,你最好为你的平等比较创建一个单独的类:

  

我们建议您从EqualityComparer类派生   而不是实现IEqualityComparer接口,因为   EqualityComparer类使用。来测试相等性   IEquatable.Equals方法而不是Object.Equals方法。这个   与Contains,IndexOf,LastIndexOf和Remove一致   Dictionary类和其他泛型的方法   集合。

因此,请创建一个类GigViewModelComparer,该类派生自EqualityComparer并将EqualsGetHashCode方法放在那里。

然后,在调用Gigs.Distinct(new GigViewModelComparer())的过程中传入一个新的比较器类的实例,它应该可以工作。请按照上面提供的MSDN链接中的示例进行操作。

我从来没有见过有人在同一个类中实现IEqualityComparer与所讨论的集合所包含的对象类型,这可能至少是你问题的一部分。