简体   繁体   English

Linq distinct不会调用Equals方法

[英]Linq distinct doesn't call Equals method

I have the following class 我有以下课程

public class ModInfo : IEquatable<ModInfo>
{
    public int ID { get; set; }
    public string MD5 { get; set; }

    public bool Equals(ModInfo other)
    {
        return other.MD5.Equals(MD5);
    }

    public override int GetHashCode()
    {
        return MD5.GetHashCode();
    }
}

I load some data into a list of that class using a method like this: 我使用如下方法将一些数据加载到该类的列表中:

public void ReloadEverything() {
    var beforeSort = new List<ModInfo>();
    // Bunch of loading from local sqlite database. 
    // not included since it's reload boring to look at
    var modinfo = beforeSort.OrderBy(m => m.ID).AsEnumerable().Distinct().ToList();
}

Problem is the Distinct() call doesn't seem to do it's job. 问题是Distinct()调用似乎没有做到这一点。 There are still objects which are equals each other. 仍然存在彼此相等的对象。

Acording to this article: https://msdn.microsoft.com/en-us/library/vstudio/bb348436%28v=vs.100%29.aspx that is how you are supposed to make distinct work, however it doesn't seem to be calling to Equals method on the ModInfo object. 根据这篇文章: https ://msdn.microsoft.com/en-us/library/vstudio/bb348436%28v=vs.100%29.aspx这是你应该如何做出截然不同的工作,但它没有似乎是在ModInfo对象上调用Equals方法。 What could be causing this to happen? 是什么导致这种情况发生?

Example values: 示例值:

modinfo[0]: id=2069, MD5 =0AAEBF5D2937BDF78CB65807C0DC047C
modinfo[1]: id=2208, MD5 = 0AAEBF5D2937BDF78CB65807C0DC047C

I don't care which value gets chosen, they are likely to be the same anyway since the md5 value is the same. 我不关心选择哪个值,因为md5值相同,它们可能是相同的。

You also need to override Object.Equals , not just implement IEquatable . 您还需要覆盖Object.Equals ,而不仅仅是实现IEquatable

If you add this to your class: 如果你把它添加到你的班级:

public override bool Equals(object other)
{
    ModInfo mod = other as ModInfo;
    if (mod != null)
        return Equals(mod);
    return false;
}

It should work. 它应该工作。

See this article for more info: Implementing IEquatable Properly 有关更多信息,请参阅此文章: 正确实现IEquatable

EDIT: Okay, here's a slightly different implementation based on best practices with GetHashCode. 编辑:好的,这是基于GetHashCode的最佳实践的略有不同的实现。

public class ModInfo : IEquatable<ModInfo>
{
    public int ID { get; set; }
    public string MD5 { get; set; }

    public bool Equals(ModInfo other)
    {
        if (other == null) return false;
        return (this.MD5.Equals(other.MD5));
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 13;
            hash = (hash * 7) + MD5.GetHashCode();
            return hash;
        }
    }

    public override bool Equals(object obj)
    {
        ModInfo other = obj as ModInfo;
        if (other != null)
        {
            return Equals(other);
        }
        else
        {
            return false;
        }
    }
}

You can verify it: 你可以验证它:

ModInfo mod1 = new ModInfo {ID = 1, MD5 = "0AAEBF5D2937BDF78CB65807C0DC047C"};
ModInfo mod2 = new ModInfo {ID = 2, MD5 = "0AAEBF5D2937BDF78CB65807C0DC047C"};

// You should get true here
bool areEqual = mod1.Equals(mod2);

List<ModInfo> mods = new List<ModInfo> {mod1, mod2};

// You should get 1 result here
mods = mods.Distinct().ToList();

What's with those specific numbers in GetHashCode? GetHashCode中的那些具体数字是什么?

Add

public bool Equals(object other)
    {
        return this.Equals(other as ModInfo)
    }

Also see here the recommendations how to implement the equality members: https://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx 另请参阅此处有关如何实现平等成员的建议: https//msdn.microsoft.com/en-us/library/ms173147(v = vs。80).aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM