¿Cuándo debo usar el operador de conversión de tipo implícito de C #?

13

En C #, podemos sobrecargar el operador de conversión implícito de esta manera (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 , mágicamente convirtiéndose a otro tipo (no relacionado), dejando a la audiencia en desconcierto (hasta que se asoman en el backstage y ver el operador de conversión implícita, que es).

No me gusta dejar a nadie que lea mi código en 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?

    
pregunta Mints97 19.05.2015 - 23:07

2 respuestas

16

Solo recomendaría conversiones implícitas entre tipos que representan aproximadamente los mismos valores de diferentes maneras. Por ejemplo:

  • Diferentes tipos de colores como RGB , HSL , HSV y CMYK .
  • Unidades diferentes para la misma cantidad física ( Meter vs Inch ).
  • Diferentes sistemas de coordenadas (polar vs cartesiano).

Sin embargo, hay algunas pautas sólidas que indican cuando no es apropiado para definir una conversión implícita:

  • Si la conversión causa una pérdida significativa de precisión o rango, entonces no debería ser implícita (por ejemplo, de float64 a float32 o de larga a int).
  • Si la conversión puede lanzar una excepción ( InvalidCast ), entonces no debería ser implícita.
  • Si la conversión provoca una asignación de almacenamiento dinámico cada vez que se realiza, no debería ser implícita.
  • Si la conversión no es una operación O(1) , entonces no debería ser implícita.
  • Si el tipo de origen o el tipo de destino es mutable, la conversión no debería ser implícita.
  • Si la conversión depende de algún tipo de contexto (base de datos, configuración cultural, configuración, sistema de archivos, etc.), entonces no debería ser implícita (en este caso, yo tampoco recomendaría un operador de conversión explícito). li>

Ahora diga que su operador de conversión f: T1 -> T2 no viola ninguna de las reglas anteriores, entonces el siguiente comportamiento indica claramente que la conversión puede ser implícita:

  • Si a == b entonces f(a) == f(b) .
  • Si a != b entonces f(a) != f(b) .
  • Si a.ToString() == b.ToString() entonces f(a).ToString() == f(b).ToString() .
  • Etc. para otras operaciones que se definen en T1 y T2 .
respondido por el Elian Ebbing 20.05.2015 - 01:22
6
  

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?

Cuando los tipos no están no relacionados (con 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 los programadores razonables).

Por ejemplo, algún código para hacer la concordancia de cadenas. Un escenario común es hacer coincidir un literal de cadena. En lugar de llamar a IsMatch(input, new Literal("some string")) , una conversión implícita le permite deshacerse de esa ceremonia, el ruido en el código, y centrarse en la cadena literal.

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 qué está sucediendo, a costa de cómo está sucediendo.

Ahora, podría argumentar que una sobrecarga de la función simple para hacer lo mismo sería mejor. Y es. Pero si este tipo de cosas son ubicuas, entonces tener una conversión es más limpio (menos código, mayor consistencia) que hacer un montón de sobrecargas de funciones.

Y podría argumentar que es mejor exigir a los programadores que creen explícitamente el tipo intermedio para que vean "lo que realmente está pasando". Eso es menos sencillo. Personalmente, creo que el ejemplo de coincidencia de cadena literal es muy claro acerca de "lo que realmente está pasando": el programador no necesita saber la mecánica de cómo todo sucede. ¿Sabe cómo se ejecuta todo su código por los distintos procesadores en los que se ejecuta su código? 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ícitos son importantes, entonces no use la conversión implícita. Si crees que son solo una ceremonia para mantener a la computadora contenta, y sería mejor que el programador no viera ese ruido en todas partes, entonces considéralo.

    
respondido por el Telastyn 19.05.2015 - 23:54

Lea otras preguntas en las etiquetas