es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

C# el operador implícito MyType(int value) “soporta” automáticamente la conversión de float.

Cuando implemento el operador de conversión de entero a mi tipo, parece que también “mágicamente” admite la conversión desde punto flotante. ¡No quiero que mi tipo se convierta implícitamente desde un flotante! No quiero que se convierta explícitamente desde flotante (definir una conversión explícita desde flotante no es suficiente).

¿Puedo evitar este comportamiento? ¿Hay alguna especificación que explique esto?

Motivo:
Estoy tratando de aprender/explorar matemáticas deterministas de punto fijo y las conversiones desde flotante son generalmente una “zona peligrosa”. Las conversiones desde entero están bien y deben ser implícitas. En los casos en que se necesitan conversiones desde flotante, prefiero un método estático para especificar mejor la intención, por ejemplo: MiNumero.ParseInseguro(0.1f).

public struct MiNumero
{
    public int crudo;

    public static implicit operator MiNumero(int x)
    {
        return new MiNumero { crudo = x * 10 };
    }
}

public static class Prueba
{
    public static void ProbarAlgo()
    {
        MiNumero num = (MiNumero)0.1f; // Esto debe causar un error de compilación, pero no lo hace.
    }
}
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para evitar la conversión implícita y explícita de float al tipo personalizado, puedes agregar un operador de conversión explícita de float al tipo personalizado que lance una excepción. De esta manera, cualquier intento de convertir de float al tipo personalizado resultará en un error del compilador.

    public static explicit operator MyNumber(float x)
    {
        throw new InvalidCastException("No se puede convertir de float a MyNumber");
    }
    

    En cuanto a la especificación que explica este comportamiento, la especificación de C# establece que en ausencia de un operador de conversión implícito o explícito para una determinada conversión, el compilador intentará realizar la conversión utilizando las conversiones incorporadas estándar. En este caso, dado que existe un operador de conversión implícito de int al tipo personalizado, el compilador puede usar su conversión incorporada de float a int y luego realizar una conversión implícita al tipo personalizado utilizando el operador de conversión definido.

Comments are closed.