C#, múltiples== sobrecargas de operador sin comprobación nula ambigua
operator-overloading null-check (3)
Lo que haría en este caso es no sobrecargar al operador ==
y, en cambio, hacer algo como:
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...
}
Introducción :
Tengo algunas clases que hacen el mismo trabajo, pero con diferentes tipos de valores (por ejemplo, Vectores de flotadores o enteros).
Ahora quiero poder verificar la igualdad, esta igualdad también debería funcionar entre los tipos (como vectorF == vectorI).
Además, debería ser posible realizar una comprobación nula (vectorF == null).
Enfoque
Mi enfoque es crear múltiples sobrecargas para los operadores == y! =, Una para cada combinación posible.
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
[...]
}
Problema
Al usar varias sobrecargas, no puedo hacer una comprobación nula con el operador ==, ya que la llamada sería ambigua.
var v = new VectorF([...]);
if (v == null) // This call is ambiguous
[...]
Soy consciente de la posibilidad de usar un ReferenceEquals o un casting nulo en su lugar, pero ese enfoque es una seria restricción para mí.
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.
[...]
Pregunta :
¿Hay una manera de implementar el operador == de una manera que permita la simple comprobación de nulos y permita la verificación de igualdad entre los diferentes vectores?
Alternativamente, ¿hay otra forma en la que podría / debería implementar esto?
Para empezar, presionaría todo el diseño. Nunca implementaría ==
con semántica de valor entre diferentes tipos, lo encontraría bastante confuso: instaceTypedA == instanceTypedB
grita la igualdad de referencia (al menos para mí).
Si necesita que esto funcione, entonces implemente una conversión implícita entre VectorI
y VectorF
. Así es como funciona el marco. Cuando haces lo siguiente:
int i = 1;
double d = 1;
var b = i == d;
Una sobrecarga ==(int, double)
no se produce mágicamente. Lo que sucede es que i
se convierte implícitamente a double
y se invoca a ==(double, double)
.
Puedes dar la vuelta a la comparación usando:
if (v is VectorF)
Esta comprobación fallará si v
es null
.