简体   繁体   English

我应该为 .NET 字典使用什么比较器来使用 EqualityComparer<t> 钥匙的方法?</t>

[英]What comparer should I use for a .NET Dictionary to use the EqualityComparer<T> methods of the Key?

My Position class is derived from the EqualityComparer<T> class.我的Position class 派生自EqualityComparer<T> class。 I would like the dictionary to use the overridden methods but it is using the methods from Object.Equals and Object.GetHashCode .我希望字典使用覆盖的方法,但它使用的是Object.EqualsObject.GetHashCode中的方法。 What comparer should I use for the Dictionary to use the EqualityComparer<T> methods of the Position class?我应该为Dictionary使用什么比较器来使用Position class 的EqualityComparer<T>方法?

using System.Collections.Generic;
using System.Diagnostics;

namespace ConsoleApp1
{
    class Position : EqualityComparer<Position>
    {
        public int X { get; set; }
        public int Y { get; set; }

        public override bool Equals(Position left, Position right)
        {
            if (left == null || right == null)
                return false;

            return left.X == right.X && left.Y == right.Y;
        }

        public override int GetHashCode(Position cell)
        {
            if (cell == null)
                return 0;

            return cell.X * 31 + cell.Y;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var dictionary = new Dictionary<Position, int>();
            var position = new Position();
            position.X = 1;
            position.Y = 1;
            dictionary[position] = 1;
            position = new Position();
            position.X = 1;
            position.Y = 1;
            var found = dictionary.TryGetValue(position, out var result);
            Debug.Assert(found);
            Debug.Assert(result == 1);
        }
    }
}

While it is very awkward unusual to implement comparer on object itself you simply need to pass an instance of comparer to the Dictionary constructor as shown in EqualityComparer example.虽然在 object 本身上实现比较器非常 尴尬 ,但您只需将比较器的实例传递给Dictionary构造函数,如EqualityComparer示例所示。

var dictionary = new Dictionary<Position, int>(new Position());

More common approach is to更常见的方法是

  • use separate class for comparer (if you need multiple variations of comparison) - implement IEquatable<T> with typed Equals and GetHashCode on the type itself (if there is a natural equality like in your case).使用单独的 class 进行比较器(如果您需要多种比较变体) - 在类型本身上使用类型化的EqualsGetHashCode实现IEquatable<T> (如果在您的情况下存在自然平等)。 This is preferable over object.Equals approach in case of value types as Equals(object) forces boxing of value types.这比object.Equals方法更可取,因为Equals(object)强制对值类型进行装箱。
  • just implement object.Equals and object.GetHashCode as shown in John's answer - this is most straightforward approach for if your type has natural equality and it is a reference type ( class ).只需实现object.Equalsobject.GetHashCode ,如约翰的答案所示 - 如果您的类型具有自然相等并且它是引用类型( class ),这是最直接的方法。

Alternative answer: You could just override Position 's GetHashCode and Equals method:替代答案:您可以覆盖PositionGetHashCodeEquals方法:

class Position
{
    public int X { get; set; }
    public int Y { get; set; }

    public override bool Equals(object other)
    {
        if (other == null || !(other is Position))
        {
            return false;
        }
        var otherPosition = (Position)other;
        return otherPosition.X == this.X && otherPosition.Y == this.Y;
    }

    public override int GetHashCode()
    {
        return this.X * 31 + this.Y;
    }
}

That way you can simply declare your dictionary like so:这样你就可以像这样简单地声明你的字典:

var dict = new Dictionary<Position, string>();

And it will work as you expect.它会按您的预期工作。

Try it online在线尝试

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

相关问题 如何对EqualityComparer使用自定义比较器 <T> 。默认? - How to use a custom comparer for EqualityComparer<T>.Default? 我可以使用Linq为C#排序字典创建比较器 - Can I use Linq to create a comparer for a C# sorted dictionary 我应该怎么做才能使用任务<t>在 .NET 2.0 中?</t> - What should I do to use Task<T> in .NET 2.0? 如何在 c# 字典中使用浮点数作为键,并使用四舍五入到最接近 .01 的自定义比较器? - How to use a float as key in c# Dictionary with custom comparer that rounds to nearest .01? 我应该使用.net的ORM? - What ORM for .net should I use? 在c#中,相等成员和相等比较器之间有什么区别,应该使用哪个? - In c#, what is the difference between equality members and an equality comparer, and which should you use? 什么是.NET Dictionary <T,T> 用于散列引用? - What does .NET Dictionary<T,T> use to hash a reference? 创建一个通用方法以使用我为特定类型定义的 EqualityComparer - Create a generic method to use EqualityComparer that I have defined for specific types 我应该重写哪些方法才能使用LINQ在哪里查找? - What methods should I override to use LINQ Where, Find? 比较器 <T> 。在.NET 4中创建 - Comparer<T>.Create in .NET 4
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM