首页 > 解决方案 > 我应该为 .NET Dictionary 使用什么比较器来使用 EqualityComparer钥匙的方法?

问题描述

我的Position类是从EqualityComparer<T>类派生的。我希望字典使用覆盖的方法,但它使用的方法来自Object.EqualsObject.GetHashCode。我应该使用什么比较器Dictionary来使用类的EqualityComparer<T>方法Position

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);
        }
    }
}

标签: c#.netdictionary

解决方案


虽然在对象本身上实现比较器非常尴尬,但您只需将比较器的实例传递给Dictionary构造函数,如EqualityComparer示例所示。

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

更常见的方法是

  • 为比较器使用单独的类(如果您需要比较的多种变体) -IEquatable<T>使用类型化EqualsGetHashCode类型本身实现(如果在您的情况下存在自然平等)。在值类型的情况下,这比object.Equals方法更可取,因为Equals(object)强制对值类型进行装箱。
  • 只需实现object.Equalsobject.GetHashCode如约翰的回答所示- 如果您的类型具有自然平等并且它是引用类型(class),这是最直接的方法。

推荐阅读