3 votes

Puis-je spécifier une valeur de constructeur en utilisant l'opérateur =?

Lorsque vous créez une chaîne en C#, vous feriez string foo = "bar"; la chaîne étant une classe, et la valeur "bar" est passée à la classe en utilisant l'opérateur =. Comment cela a-t-il été fait ? Pourriez-vous le faire dans votre propre classe ?

Je sais que c'est faisable en C++ de cette manière.

class someClass {
public:
    someClass(int someInt) {
        // Faire quelque chose
    }

};

int main() {
    someClass classInst = 123;
}

Mais quelle serait l'équivalent en C# ?

8voto

Jon Skeet Points 692016

Il y a deux parties à cette question :

  • Comment les littéraux de chaîne fonctionnent
  • Comment faire la même chose pour votre propre classe

Littéraux de chaîne

L'expression "bar" est déjà une valeur de type string. L'opérateur d'assignation copie simplement la référence, comme il le fait pour tout le reste. Les littéraux de chaîne entraînent la création d'objets de chaîne lorsque c'est possible (mais réutilisés, donc si vous avez ce code dans une boucle, il y a seulement un seul objet string). Il y a une certaine subtilité ici pour les littéraux de chaîne interpolés autour de FormattableString, mais je vais ignorer cela dans le cadre de cette question.


Créer votre propre syntaxe similaire à un littéral

Vous ne pouvez pas faire en sorte que l'opérateur d'assignation appelle directement un constructeur implicitement, non. Vous pourriez ajouter une conversion implicite de int à SomeClass, mais je le déconseillerais généralement.

Voici un exemple complet au cas où vous le voudriez vraiment, mais ce n'est vraiment pas idiomatique. Dès que vous avez des conversions implicites, cela rend plus difficile de raisonner sur la résolution des surcharges par exemple - et quiconque lit votre code doit savoir qu'il y a une conversion implicite définie par l'utilisateur.

using System;

class SomeClass
{
    public int Value { get; }

    public SomeClass(int value) => Value = value;

    public static implicit operator SomeClass(int value) =>
        new SomeClass(value);
}

public class Program
{
    static void Main()
    {
        SomeClass x = 123;
        Console.WriteLine(x.Value);
    }
}

Notez que si la fonctionnalité nouveau typé ciblé new devient disponible en C# 8, vous pourriez écrire :

SomeClass x = new(123);

... donc vous économiseriez au moins la duplication, même pour les champs.

1voto

CodeNotFound Points 595

Vous pouvez définir des conversions implicites entre les deux types: int et SomeClass comme ci-dessous :

// Conversion définie par l'utilisateur de SomeClass à int
public static implicit operator int(SomeClass someClass)
{
    return someClass.SomeInt;
}
// Conversion définie par l'utilisateur de int à SomeClass
public static implicit operator SomeClass(int someInt)
{
    return new SomeClass(someInt);
}

Ces méthodes doivent être définies dans la déclaration de SomeClass.

Pour plus d'informations sur la conversion implicite, consultez ce lien.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X