I've defined a C# class with a string member. For all intents an purposes, think of this class as being a subclass of string (except that's not allowed). I'm using it to represent a strongly typed string field that matches a specific format (I've simplified this significantly).
public class field
{
private readonly string m_field;
public field(string init_value)
{
//Check the syntax for errors
if (CheckSyntax(init_value))
{
m_field = init_value;
}
else
{
throw new ArgumentOutOfRangeException();
}
}
public override string ToString()
{
return m_field;
}
}
Now, I want to be able to compare this class directly to any other string (object or literal). Therefore, I implemented the following in the class:
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
return this.m_field == obj.ToString();
}
public override int GetHashCode()
{
return this.m_field.GetHashCode();
}
public static bool operator ==(field x, Object y)
{
if ((object)x == null && y == null)
{
return true;
}
else if ((object)x == null || y == null)
{
return false;
}
else
{
return (x.m_field == y.ToString());
}
}
public static bool operator !=(field x, Object y)
{
return !(x == y);
}
Now when I'm writing a unit test, depending on the order that I'm passing in the arguments to Assert.AreEqual, I get different results:
string valid = "Some String";
field target = new field(valid);
Assert.AreEqual(target, valid); // PASSES
Assert.AreEqual(valid, target); // FAILS
I'm assuming this is because in the first assert, it's calling field.Equals() and in the second it's calling String.Equals(). Obviously I'm approaching this from the wrong angle. Can anyone give me some insight?
One other thing. I can't use a struct here (value type) because in my actual case I'm defining all this in a base class and inheriting from it.
Basically you can't do what you want to - there's no way you can make string
recognise your class for equality purposes. You'll never be able to make it reflexive - you'll never be able to make it obey the contract of object.Equals
.
I would personally try to redesign it so that you didn't have the validation as part of the type itself - make it part of the relevant properties of the business entities (or whatever they are).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With