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 operatorpara conversões sempre seguras e sem perda de dados.explicit operatorquando 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 statice 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
- Sobrecarga de operadores aritméticos
- Sobrecarga de operadores de comparação
- Conversões definidas pelo usuário
- Boas práticas para sobrecarga de operadores