En C #, podemos sobrecargar el operador de conversión implícito como este (ejemplo de MSDN ):
struct Digit
{
/* ... */
public static implicit operator byte(Digit d) // implicit digit to byte conversion operator
{
/* ... */
}
}
Por lo tanto, podemos tener un tipo, un tipo de valor personalizado , que se convierte mágicamente a otro tipo (no relacionado), dejando a la audiencia desconcertada (hasta que se asoman al backstage y ven el operador de conversión implícito).
No me gusta dejar a nadie que lea mi código con desconcierto. No creo que mucha gente lo haga.
La pregunta es, ¿cuáles son los casos de uso del operador de conversión de tipo implícito que no harán que mi código sea mucho más difícil de entender?
Respuestas:
Solo recomendaría conversiones implícitas entre tipos que representan aproximadamente los mismos valores de diferentes maneras. Por ejemplo:
RGB
,HSL
,HSV
yCMYK
.Meter
vsInch
).Sin embargo, hay algunas pautas sólidas que indican cuando es no conveniente definir una conversión implícita:
InvalidCast
excepción ( ), entonces no debería ser implícita.O(1)
operación, entonces no debería ser implícita.Ahora digamos que su operador de conversión
f: T1 -> T2
no viola ninguna de las reglas anteriores, entonces el siguiente comportamiento indica fuertemente que la conversión puede ser implícita:a == b
entoncesf(a) == f(b)
.a != b
entoncesf(a) != f(b)
.a.ToString() == b.ToString()
entoncesf(a).ToString() == f(b).ToString()
.T1
yT2
.fuente
T1
(implicado por la==
relación enT1
) siempre se asignan a dos valores dentro de la misma clase de equivalencia deT2
. Ahora que lo pienso, supongo que la primera propiedad debería ser necesaria para una conversión implícita.Cuando los tipos no están relacionados (a los programadores). Hay escenarios (raros) en los que tiene dos tipos no relacionados (en lo que respecta al código), que están realmente relacionados (en lo que respecta al dominio o programadores razonables).
Por ejemplo, algún código para hacer coincidir cadenas. Un escenario común es hacer coincidir un literal de cadena. En lugar de llamar
IsMatch(input, new Literal("some string"))
, una conversión implícita le permite deshacerse de esa ceremonia, el ruido en el código, y enfocarse en el literal de cadena.La mayoría de los programadores verán
IsMatch(input, "some string")
e intuirán rápidamente lo que está sucediendo. Hace que su código sea más claro en el sitio de la llamada. En resumen, hace que sea un poco más fácil entender lo que está sucediendo, a un ligero costo de cómo está sucediendo.Ahora, podría argumentar que una simple sobrecarga de funciones para hacer lo mismo sería mejor. Y es. Pero si este tipo de cosas es omnipresente, entonces tener una conversión es más limpia (menos código, mayor consistencia) que hacer un montón de sobrecargas de funciones.
Y podría argumentar que es mejor requerir que los programadores creen explícitamente el tipo intermedio para que vean "lo que realmente está sucediendo". Eso es menos sencillo. Personalmente, creo que el ejemplo de coincidencia de cadena literal es muy claro sobre "lo que realmente está sucediendo": el programador no necesita conocer la mecánica de cómo sucede todo. ¿Sabe cómo se ejecutan todos los códigos en los diversos procesadores en los que se ejecuta? Siempre hay una línea de abstracción donde los programadores dejan de preocuparse por cómo funciona algo. Si cree que los pasos de conversión implícita son importantes, no utilice la conversión implícita. Si crees que son solo una ceremonia para mantener feliz a la computadora, y sería mejor que el programador no viera ese ruido en todas partes,
fuente