Una sinfonía en C#

Un pequeño aporte a la comunidad de habla hispana.

C# 6: ¿Qué son los operadores “explicit” e “implicit”?

En ocasiones nos encontramos con la necesidad de convertir entre dos tipos que no son directamente equivalentes, por ejemplo un tipo Usuario a un int, pero tal vez sea un caso válido para nosotros (sin llegar a tanto como en el ejemplo), imaginemos que tenemos un tipo Moneda, así:

public class Moneda
{
    public decimal Valor { get; set; }
    public string Simbolo { get; set; }

}

Y queremos hacer una instancia de, por ejemplo, una moneda del tipo “$”, bueno, no nos queda mucho más que hacer esto:

var a = new Moneda();
a.Simbolo = "$";

Lo cual está bien (incluso podríamos hacerlo en una línea) pero bueno, en este caso no estamos directamente convitiendo el “$” en una instancia de moneda con ese símbolo sino que estamos creando una moneda y después cambiando ese valor.

Conviertiendo entre tipos no compatibles

Bien, existe una forma de hacerlo en C#, en realidad dos formas, explícita o implícita. y son operadores, vamos a ver un ejemplo:

public class Moneda
{
    public decimal Valor { get; set; }
    public string Simbolo { get; set; }

    //permite convertir implícitamente, es decir Moneda a = "$"
    public static implicit operator Moneda(string s)
    {
        return new Moneda { Simbolo = s };
    }

    //permite convertir explícitamente, es decir Moneda a = (Moneda) 1;
    public static explicit operator Moneda(decimal i)
    {
        return new Moneda { Valor = i };
    }
}

Y como indica el código, el operador implicit permite hacer una conversión directa, en este caso igualar un tipo objeto Moneda contra un string, el explícito nos pide indicar explícitamente la conversión agregando el tipo entre paréntesis. La implementación no es una que la construcción de un objeto Moneda.

var a = new Moneda();

//conversión implícita
a = "$";

//conversión explícita
a = (Moneda) 1;

Cool, si miramos el IL vemos que lo que hace el compilador es hacer llamadas a los métodos de conversión cuando se intenta hacer la asignación

IL_0000: nop
IL_0001: newobj instance void ConsoleApplication1.Moneda::.ctor()
IL_0006: stloc.0
IL_0007: ldstr "$"
IL_000c: call class ConsoleApplication1.Moneda ConsoleApplication1.Moneda::op_Implicit(string)
IL_0011: stloc.0
IL_0012: ldsfld valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::One
IL_0017: call class ConsoleApplication1.Moneda ConsoleApplication1.Moneda::op_Explicit(valuetype [mscorlib]System.Decimal)
IL_001c: stloc.0
IL_001d: ret

Como vemos en las líneas 000c y 0017 se llama a los método op_Implicit y op_Explicit que hacen las conversiones.

Nos leemos.

Loading