[英]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.Equals
和Object.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更常见的方法是
IEquatable<T>
with typed Equals
and GetHashCode
on the type itself (if there is a natural equality like in your case).Equals
和GetHashCode
实现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)
强制对值类型进行装箱。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.Equals
和object.GetHashCode
,如约翰的答案所示 - 如果您的类型具有自然相等并且它是引用类型( class
),这是最直接的方法。 Alternative answer: You could just override Position
's GetHashCode
and Equals
method:替代答案:您可以覆盖
Position
的GetHashCode
和Equals
方法:
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.它会按您的预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.