37 votes

L'opérateur a + = b de char implémenté est-il identique à a = a + b?

Nous avons trouvé un problème intéressant: le code suivant s'exécute avec un résultat différent:

 char c = 'a';

c += 'a';   //passed
c = c + 'a'; //Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?)
 

Existe-t-il une différence entre a += b et a=a+b , ou juste la vérification du code du compilateur ratée?

Mon point est pourquoi char += char peut passer la vérification du code alors que char = (char+char) considéré char = int ?

44voto

Damien_The_Unbeliever Points 102139

Spécification C# , Section 7.17.2 Composé d'affectation:

Une opération de la forme x op= y est traitée par l'application d'opérateur binaire résolution de surcharge (§7.3.4) comme si l'opération a été écrit x op y. Ensuite,

...

• Dans le cas contraire, si l'opérateur est un opérateur prédéfini, si le type de retour de l'opérateur sélectionné est explicitement convertible pour le type d' x, et si, y est implicitement convertie dans le type d' x ou l'opérateur est un opérateur de décalage, puis l'opération est évalué comme x = (T)(x op y)T est le type d' x, sauf qu' x est évaluée qu'une seule fois

Et c'est exactement la situation que nous avons ici. Le type de retour de l'opération est d' int , mais les types d' x et y sont à la fois char, et donc un supplément de distribution est automatiquement insérée pour nous.

(Je crois que cette règle existe, car il n'y a nulle part pour vous d'être en mesure d'insérer un cast explicite vous-même et c'est une sorte de "attendus" de travail, en particulier dans les cas où l' x et y sont du même type)

9voto

Chris Points 15358

Dans le second cas, c’est l’affectation qui échoue et non le calcul lui-même. Si vous convertissez explicitement le résultat de la deuxième ligne en un caractère, cela fonctionne bien et les trois lignes suivantes génèrent un IL identique:

     c += (char)1;
    c = (char)(c + (char)1);
    c = (char)(c + 1);
 

Donc oui. Il y a une différence.

Notez à la troisième ligne que je n’ai pas pris la peine de lancer les 1 à char puisque le calcul ne fera que le reconvertir en int de toute façon.

4voto

Servé Laurijssen Points 1209

Le type résultant de + = est char dans ce cas et le type résultant de c + (char) 1 est int.

Le code suivant est imprimé:

o1 System.Char o2 System.Int32

     public static void Main(string[] args)
    {
        char c = 'a';

        object o1 = c += (char)1;
        object o2 = c + (char)1;

        WriteLine("o1 " + o1.GetType());
        WriteLine("o2 " + o2.GetType());
     }
 

2voto

DerClef Points 111

Pour mettre Damien réponse en termes plus simples:
Composé d'opérateurs (par exemple, +=, -= etc.) convertis automatiquement le résultat de la cible (si possible). Par conséquent, c += 'a' fonctionne, parce qu'il est évalué comme c = (char)(c + 'a').

Dans ce cas, la conversion est nécessaire, car le retour de type d'opérations arithmétiques entre les caractères est - int (c'est pourquoi c = c + 'a' ne compile pas, comme il est absent de la fonte ci-dessus).

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