实现IEqualityComparer

kat*_*330 8 c#

我想从列表中获取不同的对象.我试图实施,IEqualityComparer但没有成功.请查看我的代码并给我一个解释IEqualityComparer.

public class Message
{
    public int x { get; set; }
    public string y { get; set; }
    public string z { get; set; }
    public string w { get; set; }
}

public class MessageComparer : IEqualityComparer<Message>
{
    public bool Equals(Message x, Message y)
    {
        if (Object.ReferenceEquals(x, y)) return true;

        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        if (x.x == y.x && x.y == y.y && x.z == y.z && x.w == y.w)
        {
            return true;
        }

        return false;
    }

    public int GetHashCode(Message number)
    {
        // if (Object.ReferenceEquals(number, null)) return 0;
        int hashX = number.x.GetHashCode();
        int hashY = number.y == null ? 0 : number.y.GetHashCode();
        int hashZ = number.z == null ? 0 : number.z.GetHashCode();
        int hashW = number.w == null ? 0 : number.w.GetHashCode();

        return hashX ^ hashY ^ hashZ ^ hashW;           
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我ListMessage对象:

Message m1 = new Message();
m1.x = 1;
m1.y = "A";
m1.z = "B";
m1.w = "C";

Message m2 = new Message();
m2.x = 1;
m2.y = "A";
m2.z = "B";
m2.w = "C";

Message m3 = new Message();
m3.x = 1;
m3.y = "A";
m3.z = "B";
m3.w = "C";

Message m4 = new Message();
m4.x = 2;
m4.y = "A";
m4.z = "B";
m4.w = "C";

Message m5 = new Message();
m5.x = 3;
m5.y = "W";
m5.z = "D";
m5.w = "C";

Message m6 = new Message();
m6.x = 4;
m6.y = "S";
m6.z = "F";
m6.w = "R";

List<Message> collection = new List<Message>();
collection.Add(m1);
collection.Add(m2);
collection.Add(m3);
collection.Add(m4);
collection.Add(m5);

collection.Distinct(new MessageComparer());
Run Code Online (Sandbox Code Playgroud)

当我调用该Distinct()方法时,元素的数量collection是相同的.

Mat*_*gen 13

试试这个:

var distinct = collection.Distinct(new MessageComparer());
Run Code Online (Sandbox Code Playgroud)

然后distinct在那之后使用任何东西.

看起来你忘记了它的不变性IEnumerable<>.LINQ方法都没有实际更改原始变量.相反,它们返回IEnuerable<T>包含表达式结果的s.例如,让我们考虑List<string> original一下内容的简单{ "a", "a", "b", "c" }.

现在,让我们打电话original.Add("d");.该方法没有返回值(它是void).但是,如果我们打印出内容original,我们会看到{ "a", "a", "b", "c", "d" }.

另一方面,我们现在打电话original.Skip(1).此方法确实具有返回值,类型之一IEnumerable<string>.它是一个LINQ表达式,不对原始集合执行任何副作用操作.因此,如果我们打电话给那看original,我们就会看到{ "a", "a", "b", "c", "d" }.但是,该方法的结果将是{ "a", "b", "c", "d" }.如您所见,结果会跳过一个元素.

这是因为LINQ方法接受IEnumerable<T>作为参数.因此,他们没有实施原始清单的概念.您可以通过扩展方法传递a ReadOnlyCollection,他们仍然可以通过它进行评估.因此,它们不能改变原始集合,因为原始集合可以以多种方式编写.

所有这一切,但以表格形式.每行以原始行开头{ "a", "a", "b", "c" }:

Context     Example function    Immutable?    Returned Value     Collection after calling
Collection  Add("d")            No            (void)             { "a", "a", "b", "c", "d" }:
LINQ        Skip(1)             Yes           { "a", "b", "c" }  { "a", "a", "b", "c" }:
Run Code Online (Sandbox Code Playgroud)


小智 5

IEqualityComparer是一个用于判断对象是否相等的接口。我们将在一个示例中看到这一点,我们必须在一个集合中找到不同的对象。该接口将实现该方法Equals(T obj1,T obj2)

abstract public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { set; get; }
}

public enum SortType
{
    ByID,
    BySalary
}

public class EmployeeDistinctEquality : IEqualityComparer<Employee>
{
    public EmployeeDistinctEquality()
    {

    }

    public bool Equals(Employee x, Employee y)
    {
        if (x == null && y == null)
            return true;
        else if (x == null || y == null)
            return false;
        else if (x.Id == y.Id)
            return true;
        else
            return false;
    }

    public int GetHashCode(Employee obj)
    {
        return obj.Id.GetHashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅此链接:

http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html