0Pricing
C# Academy · Aula

Conversões definidas pelo usuário

Adicione operadores de conversão implícita e explícita.

Conversões definidas pelo usuário é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.

Conversões definidas pelo usuário

O C# permite que um tipo defina como ele é convertido para outro tipo ou a partir dele usando os operadores implicit e explicit. Conversões implícitas acontecem automaticamente; as explícitas exigem uma conversão explícita.

Uma conversão implícita

Use implicit operator quando uma conversão for sempre segura e sem perda de informação. O compilador a aplica automaticamente sempre que o tipo de destino for esperado.

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);
    }
}

Uma conversão explícita

Use explicit operator quando uma conversão puder perder informações ou falhar. Os chamadores devem escrever uma conversão explícita, sinalizando que aceitam o risco.

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);
    }
}

Convertendo para seu tipo

As conversões também podem ocorrer no sentido contrário: de outro tipo para o seu. Aqui, um operador implicit cria um Celsius a partir de um double bruto.

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 ou explícita: como escolher

A regra prática é: torne a conversão implícita somente se ela nunca perder dados nem lançar exceções. Se ela puder perder precisão, causar estouro ou falhar, torne-a 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);
    }
}

Conversões entre tipos personalizados

As conversões não se limitam aos tipos integrados. Você pode converter entre dois tipos próprios, por exemplo, de coordenadas polares para 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);
    }
}

Conversões combinam-se com operadores

Depois que uma conversão existe, o valor participa de expressões do tipo de destino. Uma conversão implícita para double permite usar seu tipo diretamente em operações 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 conversões implícitas surpreendentes

Conversões implícitas que não são obviamente seguras podem esconder erros, porque o compilador as aplica silenciosamente. Em caso de dúvida, prefira a forma explícita para que a intenção fique visível no 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);
    }
}

Operadores de conversão são estáticos

Assim como os demais operadores, os operadores de conversão são public static. Exatamente um dos tipos envolvidos deve ser o tipo que declara o 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);
    }
}

Um tipo de encapsulamento prático

As conversões são especialmente úteis para tipos de encapsulamento simples que fortalecem o sistema de tipos sem criar atrito. Aqui, NonEmptyString é convertido implicitamente para string, mas sua criação exige uma conversão explícita.

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);
    }
}

Experimente você mesmo

Defina um tipo de encapsulamento com uma conversão implícita de saída (segura) e uma conversão explícita de entrada (validada). Observe qual direção exige uma conversão de tipo.

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 + "%");
    }
}

Verificação rápida

Escolha o tipo correto de conversão.

Recapitulação

As conversões definidas pelo usuário permitem que seus tipos interoperem de forma simples.

  • implicit operator para conversões sempre seguras e sem perda de dados.
  • explicit operator quando dados podem ser perdidos ou a conversão pode falhar.
  • As conversões podem ter como destino tipos integrados ou personalizados, em qualquer direção.
  • Elas são public static e declaradas por um dos tipos envolvidos.

Perguntas Frequentes

A aula “Conversões definidas pelo usuário” é grátis?

Sim — o texto completo de “Conversões definidas pelo usuário” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.

O que vou aprender em “Conversões definidas pelo usuário”?

Adicione operadores de conversão implícita e explícita. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C# Academy?

Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Conversões definidas pelo usuário”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C# Academy?

Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Sobrecarga de operadores aritméticos
  2. Sobrecarga de operadores de comparação
  3. Conversões definidas pelo usuário
  4. Boas práticas para sobrecarga de operadores
← Voltar para C# Academy