0Pricing
C# Academy · Leçon

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 operator pour les conversions toujours sûres et sans perte.
  • explicit operator lorsque 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 static et 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

  1. Surcharge des opérateurs arithmétiques
  2. Surcharge des opérateurs de comparaison
  3. Conversions définies par l’utilisateur
  4. Bonnes pratiques pour la surcharge des opérateurs
← Retour à C# Academy