I have this class
class Border { int top; int bottom; int left; int right; }
And I have a
Dictionary
withBorder
as a key.
I want to have the same key for this class, if these two values are equal. How can I do it?
I have this class
class Border
{
int top;
int bottom;
int left;
int right;
}
And I have a Dictionary
with Border
as a key.
I want to have the same key for this class, if these two values are equal. How can I do it?
So, if these need to go as keys in a dictionary, then your class needs to be immutable. Then it's a case of adding equality and a hashcode implementation (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; }
}
}
I'm not sure whether you mean one of two opposite things.
If you mean that you want to make sure two different instances of border
are counted as being the same key if their values are the same then you need to redefine equality.
Step 1. Implement IEquatable<Border>
, while you don't need to do so, it makes some things faster to run and other things simpler to code.
Step 2. Add your code to implement the Equals
method this requires:
public bool Equals(Border other)
{
return other != null
&& other.bottom == bottom
&& other.top == top
&& other.left == left
&& other.right == right;
}
Edit: As JLRishe points out in a comment on another answer, if this class isn't sealed then the above method should check GetType() == other.GetType()
after the null check, unless it has a very good reason not to).
Step 3. Add an override for object.Equals
and 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;
}
Now the default behaviour of your class when used in a dictionary will be to treat those Border
objects with the same bottom, top, left and right as being the same thing.
Alternatively, maybe you mean you've already got that, and you want to have two equal objects treated as differently for some reason (as if they didn't have a specific sense of equivalence defined for them). You can't do that in pure C# without reflection emit, so I wrote http://www.nuget.org/packages/AisA/ for the few times it's useful.