IEqualityComparer含义

时间:2010-02-26 07:11:50

标签: c# linq linq-to-objects

考虑这个数组

        string[] presidents = {
            "Adams", "Arthur", "Buchanan", "Bush", "Carter", "Cleveland",
            "Clinton", "Coolidge", "Eisenhower", "Fillmore", "Ford", "Garfield",
            "Grant", "Harding", "Harrison", "Hayes", "Hoover", "Jackson",
            "Jefferson", "Johnson", "Kennedy", "Lincoln", "Madison", "McKinley",
            "Monroe", "Nixon", "Pierce", "Polk", "Reagan", "Roosevelt", "Taft",
            "Taylor", "Truman", "Tyler", "Van Buren", "Washington", "Wilson"};

我的分组标准是一组中长度为1到5的名称,并保留在其他组中 我使用这个派生类

实现了这个
class MyLengthComparer:IEqualityComparer<Int32>
{
    public Int32 GetHashCode(Int32 i)
    {
        return i<=5?1:6;
    }


    public Boolean Equals(Int32 i1,Int32 i2)
    {
        if(i1<=5 && i2<=5)
            return true;
        if(i1>5 && i2>5)
            return true;
        else
            return false;
    }
}

现在我运行

        IEnumerable<IGrouping<Int32, String>> groupVar = presidents.GroupBy(prez=>prez.Length,new MyLengthComparer());
        foreach(IGrouping<Int32, String> grp in groupVar)
        {
            Console.WriteLine("******" + grp.Key + "******" );
            foreach(String name in grp)
                Console.WriteLine(name);
        }

        Console.ReadKey();

我想知道IEqualityInterface的两个函数的含义。我的意思是如何进行比较。
Key in IGrouping的意义是什么,为什么显示5和6?

1 个答案:

答案 0 :(得分:2)

它显示5和6,因为组的键被认为是从第一个项创建的键。 “Adams”的长度为5,“Arthur”的长度为6,因此这些是该组的关键。

小组的关键是小组中的所有内容都应该具有共同点。你的比较器在这方面相当奇怪。

基本上,序列中的每个元素都被投射到键(名称的长度),然后进行查找以找出该键是否已经有一个组。该查找需要哈希代码(因为它是基于哈希的查找)和相等 - 这就是您的自定义比较器提供的内容。它根据长度给出1或6的散列(实际数字相对不重要;它们与相等一致,这意味着查找将起作用,它们是不同的,这意味着它将是有效的)。相等函数本身实际上只是“这两个值在小于或等于5时是相同的”。我可能会把它实现为:

public Boolean Equals(Int32 i1,Int32 i2)
{
    return (i1 <= 5) == (i2 <= 5);
}

实际上,通过使用x => x.Name.Length <= 5的关键投影并且不提供自定义比较器,您可以更明显地获得相同的分组(使用不同的密钥):

var groups = presidents.GroupBy(prez => prez.Length <= 5);
foreach(var group in groups)
{
    // This time the key will be true or false
    Console.WriteLine("******" + group.Key + "******" );
    foreach(String name in group)
    {
        Console.WriteLine(name);
    }
}