Reputation: 465
Introduction:
I have a few classes which do the same work, but with different value types (e.g. Vectors of floats or integers).
Now I want to be able to check for equality, this equality should also work in between the types (such as vectorF == vectorI).
Also, it should be possible to do a null check (vectorF == null).
Approach:
My approach is to create multiple overloads for the == and != operators, one for each possible combination.
public sealed class VectorF
{
[...]
public static bool operator == (VectorF left, VectorI right)
{
// Implementation...
}
public static bool operator == (VectorF left, VectorF right)
{
// Implementation...
}
// Same for != operator
[...]
}
Problem:
Using multiple overloads, I cannot just do a null check with the == operator, as the call would be ambiguous.
var v = new VectorF([...]);
if (v == null) // This call is ambiguous
[...]
I'm aware of the possibility to use a ReferenceEquals or null casting instead, but that approachis a serious restriction for me.
var v = new VectorF([...]);
if(object.ReferenceEquals(v, null)) // Would work, is not user friendly.
[...]
if(v == (VectorF)null) // Would also work, is neither user friendly.
[...]
Question:
Is there a way to implement the == operator in a way, that it allows the simple null check, and allows for equality check between the different vectors?
Alternatively, is there another way how I could/should implement this?
Upvotes: 18
Views: 2671
Reputation: 32750
I'd push back on the whole design to begin with. I would never implement ==
with value semantics between different types, I'd find it rather confusing: instaceTypedA == instanceTypedB
yells reference equality (at least to me).
If you need this to work, then implement an implicit conversion between VectorI
and VectorF
. This is how the framework works. When you do the following:
int i = 1;
double d = 1;
var b = i == d;
An oveload ==(int, double)
isn't magically produced. What happens is that i
is implicitly converted to double
and ==(double, double)
is invoked.
Upvotes: 20
Reputation: 57202
What I would do in this case it not to overload the ==
operator, and instead do something like:
public static bool operator == (VectorF left, object right) {
if (object.ReferenceEquals(null, right)) {
// handle null case
}
VectorF rightF = right as VectorF;
if (!object.ReferenceEquals(null, rightF)) {
// Compare VectorF
}
VectorI rightI = right as VectorI;
if (!object.ReferenceEquals(null, rightI)) {
// Compare VectorI
}
// and so on...
}
Upvotes: 3
Reputation: 156978
You can turn around the comparison by using is
:
if (v is VectorF)
This check will fail if v
is null
.
Upvotes: 7