我有这个班级
class Border
{
int top;
int bottom;
int left;
int right;
}
我有Dictionary
Border
作为密钥。
如果这两个值相等,我想为这个类使用相同的键。我该怎么办?
答案 0 :(得分:4)
因此,如果这些需要作为字典中的键,那么your class needs to be immutable。然后是添加相等性和哈希码实现(thankyou resharper)的情况。
public class Border
{
private readonly int bottom;
private readonly int left;
private readonly int right;
private readonly int top;
public Border(int top, int left, int bottom, int right)
{
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
protected bool Equals(Border other)
{
return bottom == other.bottom && left == other.left && right == other.right && top == other.top;
}
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((Border) obj);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = bottom;
hashCode = (hashCode*397) ^ left;
hashCode = (hashCode*397) ^ right;
hashCode = (hashCode*397) ^ top;
return hashCode;
}
}
public static bool operator ==(Border left, Border right)
{
return Equals(left, right);
}
public static bool operator !=(Border left, Border right)
{
return !Equals(left, right);
}
public int Top
{
get { return top; }
}
public int Bottom
{
get { return bottom; }
}
public int Left
{
get { return left; }
}
public int Right
{
get { return right; }
}
}
答案 1 :(得分:0)
我不确定你的意思是否是两个相反的事情之一。
如果您希望确保border
的两个不同实例在其值相同的情况下被视为同一个键,那么您需要重新定义相等。
步骤1.实施IEquatable<Border>
,虽然您不需要这样做,但它可以让一些事情更快地运行,而其他更简单的代码。
步骤2.添加代码以实现此要求的Equals
方法:
public bool Equals(Border other)
{
return other != null
&& other.bottom == bottom
&& other.top == top
&& other.left == left
&& other.right == right;
}
编辑:正如JLRishe在对另一个答案的评论中指出的那样,如果这个类没有被密封,那么上面的方法应该在空检查之后检查GetType() == other.GetType()
,除非它有非常好的理由不这样做)。
步骤3.为object.Equals
和object.GetHashCode
添加覆盖:
public override bool Equals(object other)
{
return Equals(other as Border);
}
public override int GetHashCode()
{
//This is a simple method without very good distribution, that will serve for many cases, but can be improved upon.
return (bottom << 24 | bottom >> 8)
^ (top << 16 | top >> 16)
^ (left << 8 | left >> 8)
^ right;
}
现在,在字典中使用时,类的默认行为是将具有相同底部,顶部,左侧和右侧的Border
个对象视为同一事物。
或者,也许你的意思是你已经有了这个,并且你希望有两个相同的对象由于某种原因被视为不同(就好像它们没有为它们定义的特定的等效感)。你不能在没有反射发射的纯C#中做到这一点,所以我写了http://www.nuget.org/packages/AisA/几次它是有用的。