Conversions définies par l’utilisateur
Ajoutez des opérateurs de conversion implicites et explicites.
Conversions définies par l’utilisateur est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C# Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C# Academy comprend 4 leçons au total.
Conversions définies par l’utilisateur
C# permet à un type de définir sa conversion vers un autre type ou depuis celui-ci à l’aide des opérateurs implicit et explicit. Les conversions implicites s’effectuent automatiquement ; les conversions explicites nécessitent une conversion forcée.
Une conversion implicite
Utilisez implicit operator lorsqu’une conversion est toujours sûre et sans perte. Le compilateur l’applique automatiquement partout où le type cible est attendu.
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);
}
}Une conversion explicite
Utilisez explicit operator lorsqu’une conversion peut entraîner une perte d’informations ou échouer. Les appelants doivent écrire une conversion forcée, signalant ainsi qu’ils acceptent le risque.
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 vers votre type
Les conversions peuvent également s’effectuer dans l’autre sens : depuis un autre type vers le vôtre. Ici, un opérateur implicit construit un Celsius à partir d’un double brut.
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);
}
}Implicite ou explicite : choisir
Règle générale : ne la rendez implicite que si elle ne perd jamais de données et ne lève jamais d'exception. Si elle peut entraîner une perte de précision, un dépassement de capacité ou un échec, rendez-la explicite.
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);
}
}Conversions entre types personnalisés
Les conversions ne se limitent pas aux types intégrés. Vous pouvez convertir deux de vos propres types l'un vers l'autre, par exemple des coordonnées Polar en coordonnées Cartesian.
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);
}
}Les conversions se combinent avec les opérateurs
Une fois une conversion définie, la valeur participe aux expressions du type cible. Une conversion implicite vers double permet d'utiliser directement votre type dans des opérations arithmétiques.
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);
}
}Éviter les conversions implicites surprenantes
Les conversions implicites qui ne sont pas manifestement sûres peuvent dissimuler des bogues, car le compilateur les applique silencieusement. En cas de doute, préférez une conversion explicite afin que l'intention soit visible dans le code.
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);
}
}Les opérateurs de conversion sont statiques
Comme les autres opérateurs, les opérateurs de conversion sont public static. Exactement l'un des types concernés doit être le type qui déclare l'opérateur.
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 type enveloppe pratique
Les conversions sont particulièrement utiles avec de petits types enveloppes qui renforcent le système de types sans ajouter de contrainte. Ici, NonEmptyString est converti implicitement en string, mais sa création nécessite une conversion explicite.
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);
}
}Essayez vous-même
Définissez un type enveloppe avec une conversion implicite vers l'extérieur (sûre) et une conversion explicite vers l'intérieur (validée). Remarquez dans quel sens une conversion est nécessaire.
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 + "%");
}
}Vérification rapide
Choisissez le type de conversion approprié.
Récapitulatif
Les conversions définies par l'utilisateur permettent à vos types d'interagir harmonieusement.
implicit operatorpour les conversions toujours sûres et sans perte.explicit operatorlorsque des données peuvent être perdues ou que la conversion peut échouer.- Les conversions peuvent cibler des types intégrés ou personnalisés, dans un sens comme dans l'autre.
- Elles sont
public staticet sont déclarées par l'un des types concernés.
Questions Fréquemment Posées
La leçon « Conversions définies par l’utilisateur » est-elle gratuite ?
Oui — le texte complet de « Conversions définies par l’utilisateur » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C# Academy, passe à CoddyKit PRO. Le cours C# Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Conversions définies par l’utilisateur » ?
Ajoutez des opérateurs de conversion implicites et explicites. Tu pratiques C# Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C# Academy ?
Aucune expérience préalable n'est requise. C# Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Conversions définies par l’utilisateur » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C# Academy ?
Oui. Chaque leçon C# Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Surcharge des opérateurs arithmétiques
- Surcharge des opérateurs de comparaison
- Conversions définies par l’utilisateur
- Bonnes pratiques pour la surcharge des opérateurs