首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >实施IEqualityComparer

实施IEqualityComparer
EN

Stack Overflow用户
提问于 2014-07-24 10:16:37
回答 3查看 21.6K关注 0票数 11

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

代码语言:javascript
运行
复制
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;           
    }
}

这是我的带有Message对象的List

代码语言:javascript
运行
复制
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());

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-24 10:22:35

试试这个:

代码语言:javascript
运行
复制
var distinct = collection.Distinct(new MessageComparer());

然后在那之后的任何事情上使用distinct

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

现在,让我们调用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>作为参数。因此,他们对原始列表的实现没有概念。您可以通过扩展方法传递一个ReadOnlyCollection,而他们仍然能够通过它进行计算。因此,它们不能更改原始集合,因为原始集合可以以任意数量的方式编写。

所有这些,但以表格的形式。每行都以原始{ "a", "a", "b", "c" }开头

代码语言:javascript
运行
复制
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" }:
票数 13
EN

Stack Overflow用户

发布于 2016-09-09 11:53:14

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

代码语言:javascript
运行
复制
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();
    }
}

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

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

票数 7
EN

Stack Overflow用户

发布于 2014-07-24 10:23:57

你不需要实现IEqualityComparer

代码语言:javascript
运行
复制
public class Message
{
    protected bool Equals(Message other)
    {
        return string.Equals(x, other.x) && string.Equals(y, other.y) && string.Equals(z, other.z) && string.Equals(w, other.w);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Message) obj);
    }

    public override int GetHashCode()
    {
        unchecked //Ignores overflows that can (should) occur
        {
            var hashCode = x;
            hashCode = (hashCode*397) ^ (y != null ? y.GetHashCode() : 0);
            hashCode = (hashCode*397) ^ (z != null ? z.GetHashCode() : 0);
            hashCode = (hashCode*397) ^ (w != null ? w.GetHashCode() : 0);
            return hashCode;
        }
    }

    public int x { get; set; }
    public string y { get; set; }
    public string z { get; set; }
    public string w { get; set; }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24924071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档