0Pricing
C# Academy · Lección

Conversiones definidas por el usuario

Añada operadores de conversión implícitos y explícitos.

Conversiones definidas por el usuario es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.

Conversiones definidas por el usuario

C# permite que un tipo defina cómo se convierte a otro tipo o desde él mediante los operadores implicit y explicit. Las conversiones implícitas se realizan automáticamente; las explícitas requieren una conversión explícita.

Una conversión implícita

Use implicit operator cuando una conversión sea siempre segura y no pierda información. El compilador la aplica automáticamente en cualquier lugar donde se espere el tipo de destino.

using System;

public struct Celsius
{
    public double Degrees;
    public Celsius(double d) { Degrees = d; }

    // Always safe: a Celsius is just a number
    public static implicit operator double(Celsius c) => c.Degrees;
}

public class Program
{
    public static void Main()
    {
        Celsius temp = new Celsius(21.5);
        double d = temp; // implicit, no cast needed
        Console.WriteLine(d);
    }
}

Una conversión explícita

Use explicit operator cuando una conversión pueda perder información o fallar. Quien la llama debe escribir una conversión explícita, lo que indica que acepta el riesgo.

using System;

public struct Money
{
    public decimal Amount;
    public Money(decimal a) { Amount = a; }

    // Loses the fractional cents, so make it explicit
    public static explicit operator int(Money m) => (int)m.Amount;
}

public class Program
{
    public static void Main()
    {
        var m = new Money(19.99m);
        int dollars = (int)m; // explicit cast required
        Console.WriteLine(dollars);
    }
}

Convertir a su tipo

Las conversiones también pueden funcionar en el otro sentido: desde otro tipo al suyo. En este caso, un operador implicit crea un Celsius a partir de un double.

using System;

public struct Celsius
{
    public double Degrees;
    public Celsius(double d) { Degrees = d; }

    public static implicit operator Celsius(double d) => new Celsius(d);

    public override string ToString() => Degrees + "C";
}

public class Program
{
    public static void Main()
    {
        Celsius t = 18.0; // double implicitly becomes Celsius
        Console.WriteLine(t);
    }
}

Implícita vs explícita: cómo elegir

Regla general: haga la conversión implícita solo si nunca pierde datos ni produce excepciones. Si puede perder precisión, producir un desbordamiento o fallar, hágala explícita.

using System;

public struct Percentage
{
    public double Value; // 0..1
    public Percentage(double v) { Value = v; }

    // Safe and lossless -> implicit
    public static implicit operator double(Percentage p) => p.Value;
    // Could be out of range -> explicit
    public static explicit operator Percentage(double v) => new Percentage(v);
}

public class Program
{
    public static void Main()
    {
        double d = new Percentage(0.25);
        var p = (Percentage)0.5;
        Console.WriteLine(d + " " + p.Value);
    }
}

Conversiones entre tipos personalizados

Las conversiones no se limitan a los tipos integrados. Puede convertir entre dos tipos propios, por ejemplo, de coordenadas polares a coordenadas cartesianas.

using System;

public struct Cartesian
{
    public double X, Y;
    public Cartesian(double x, double y) { X = x; Y = y; }
    public override string ToString() => "(" + Math.Round(X, 2) + ", " + Math.Round(Y, 2) + ")";
}

public struct Polar
{
    public double R, Theta;
    public Polar(double r, double theta) { R = r; Theta = theta; }
    public static explicit operator Cartesian(Polar p)
        => new Cartesian(p.R * Math.Cos(p.Theta), p.R * Math.Sin(p.Theta));
}

public class Program
{
    public static void Main()
    {
        var c = (Cartesian)new Polar(1.0, 0.0);
        Console.WriteLine(c);
    }
}

Las conversiones se combinan con los operadores

Una vez definida una conversión, el valor puede participar en expresiones del tipo de destino. Una conversión implícita a double permite usar el tipo directamente en operaciones aritméticas.

using System;

public struct Meters
{
    public double Value;
    public Meters(double v) { Value = v; }
    public static implicit operator double(Meters m) => m.Value;
}

public class Program
{
    public static void Main()
    {
        var distance = new Meters(5);
        double doubled = distance * 2; // uses implicit conversion to double
        Console.WriteLine(doubled);
    }
}

Evite las conversiones implícitas inesperadas

Las conversiones implícitas que no son claramente seguras pueden ocultar errores, porque el compilador las aplica silenciosamente. En caso de duda, prefiera la conversión explícita para que la intención sea visible en el código.

using System;

public struct UserId
{
    public int Value;
    public UserId(int v) { Value = v; }
    // Explicit on purpose: an int is not always a valid id
    public static explicit operator UserId(int v) => new UserId(v);
    public static explicit operator int(UserId id) => id.Value;
}

public class Program
{
    public static void Main()
    {
        var id = (UserId)42;
        int raw = (int)id;
        Console.WriteLine(raw);
    }
}

Los operadores de conversión son static

Al igual que otros operadores, los operadores de conversión son public static. Exactamente uno de los tipos involucrados debe ser el tipo que declara el operador.

using System;

public struct Fahrenheit
{
    public double Degrees;
    public Fahrenheit(double d) { Degrees = d; }
    public static implicit operator Fahrenheit(double d) => new Fahrenheit(d);
    public static implicit operator double(Fahrenheit f) => f.Degrees;
    public override string ToString() => Degrees + "F";
}

public class Program
{
    public static void Main()
    {
        Fahrenheit f = 98.6;
        double d = f;
        Console.WriteLine(f + " = " + d);
    }
}

Un tipo envoltorio práctico

Las conversiones resultan muy útiles para tipos envoltorio ligeros que refuerzan el sistema de tipos sin añadir fricción. Aquí, NonEmptyString se convierte implícitamente en string, pero requiere una conversión explícita para crearse.

using System;

public struct NonEmptyString
{
    public string Value;
    public NonEmptyString(string v)
    {
        if (string.IsNullOrEmpty(v)) throw new ArgumentException("empty");
        Value = v;
    }
    public static explicit operator NonEmptyString(string s) => new NonEmptyString(s);
    public static implicit operator string(NonEmptyString s) => s.Value;
}

public class Program
{
    public static void Main()
    {
        var name = (NonEmptyString)"Ada";
        string s = name;
        Console.WriteLine(s);
    }
}

Póngalo en práctica

Defina un envoltorio con una conversión implícita de salida (segura) y una conversión explícita de entrada (validada). Observe qué dirección requiere una conversión explícita.

using System;

public struct Ratio
{
    public double Value;
    public Ratio(double v)
    {
        if (v < 0 || v > 1) throw new ArgumentOutOfRangeException(nameof(v));
        Value = v;
    }
    public static implicit operator double(Ratio r) => r.Value; // always safe
    public static explicit operator Ratio(double v) => new Ratio(v); // may throw
}

public class Program
{
    public static void Main()
    {
        var half = (Ratio)0.5;   // explicit, validated
        double d = half;          // implicit, safe
        Console.WriteLine(d * 100 + "%");
    }
}

Comprobación rápida

Elija el tipo de conversión adecuado.

Resumen

Las conversiones definidas por el usuario permiten que sus tipos interoperén correctamente.

  • implicit operator para conversiones siempre seguras y sin pérdida.
  • explicit operator cuando se pueden perder datos o la conversión puede fallar.
  • Las conversiones pueden dirigirse a tipos integrados o personalizados, en cualquiera de las dos direcciones.
  • Son public static y las declara uno de los tipos involucrados.

Preguntas frecuentes

¿La lección «Conversiones definidas por el usuario» es gratis?

Sí — el texto completo de «Conversiones definidas por el usuario» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Conversiones definidas por el usuario»?

Añada operadores de conversión implícitos y explícitos. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C# Academy?

No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Conversiones definidas por el usuario»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C# Academy?

Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Sobrecarga de operadores aritméticos
  2. Sobrecarga de operadores de comparación
  3. Conversiones definidas por el usuario
  4. Prácticas recomendadas para sobrecargar operadores
← Volver a C# Academy