Question

J'ai le code C# suivant :

byte rule = 0;
...
rule = rule | 0x80;

ce qui produit l'erreur :

Impossible de convertir implicitement le type « int » en « octet ».Une conversion explicite existe (il vous manque un casting ?)

[Mise à jour:la première version de la question était fausse...J'ai mal lu la sortie du compilateur]

Ajout du casting n'a pas résoudre le problème:

rule = rule | (byte) 0x80;

Je dois l'écrire comme suit :

rule |= 0x80;

Ce qui semble bizarre.Pourquoi est-ce que |= opérateur différent du | opérateur?

Existe-t-il un autre moyen de dire au compilateur de traiter la constante comme un octet ?


@Giovanni Galbo :Oui et non.Le code concerne la programmation de la mémoire flash dans un périphérique externe et représente logiquement un seul octet de mémoire.Je pourrais le lancer plus tard, mais cela semblait plus évident.Je suppose que mon héritage C transparaît trop !

@ Jonathan Holland :la syntaxe 'as' semble plus soignée mais ne semble malheureusement pas fonctionner...cela produit:

L'opérateur as doit être utilisé avec un type référence ou un type nullable (« octet » est un type valeur non nullable)

Était-ce utile?

La solution

int rule = 0;
rule |= 0x80;

http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx Le | L'opérateur est défini pour tous les types de valeur.Je pense que cela produira le résultat escompté.L'opérateur "| =" est un opérateur d'attribution ou ensuite, qui est simplement un raccourci pour la règle = règle | 0x80.

L'un des aspects les plus intéressants de C# est qu'il vous permet de faire des choses folles, comme abuser des types de valeurs simplement en fonction de leur taille.Un 'int' est exactement la même chose qu'un octet, sauf que le compilateur émettra des avertissements si vous essayez de les utiliser comme les deux en même temps.S'en tenir simplement à un (dans ce cas, int) fonctionne bien.Si vous êtes préoccupé par la préparation au 64 bits, vous pouvez spécifier int32, mais tous les entiers sont des int32, même s'exécutant en mode x64.

Autres conseils

C# n'a pas de suffixe littéral pour l'octet.u = uint, l = long, ul = ulong, f = float, m = décimal, mais pas d'octet.Vous devez le lancer.

Cela marche:

rule = (byte)(rule | 0x80);

Apparemment, la règle d'expression | 0x80 'Renvoie un int même si vous définissez 0x80 comme' const octet 0x80 '.

Le terme que vous recherchez est « Littéral » et malheureusement, C# n’a pas d’octet littéral.

Voici une liste de tous les littéraux C#.

Selon le Spécification ECMA, page 72 il n'y a pas d'octet littéral.Uniquement des littéraux entiers pour les types :int, uint, long et ulong.

On dirait que vous devrez peut-être procéder de la manière la plus vilaine : http://msdn.microsoft.com/en-us/library/5bdb6693.aspx.

Près de cinq ans plus tard, personne n’a encore répondu à la question.

Quelques réponses affirment que le problème est le manque d'octet littéral, mais cela n'a pas d'importance.Si vous calculez (byte1 | byte2) le résultat est du type int.Même si "b" était un suffixe littéral pour octet, le type de (23b | 32b) serait toujours int.

La réponse acceptée renvoie à un article MSDN affirmant que operator| est défini pour tous les types intégraux, mais ce n'est pas vrai non plus.

operator| n'est pas défini sur byte le compilateur utilise donc ses règles habituelles de résolution de surcharge pour sélectionner la version définie sur int.Par conséquent, si vous souhaitez attribuer le résultat à un byte vous devez le lancer :

rule = (byte)(rule | 0x80);

La question demeure, pourquoi rule |= 0x80; travail?

Parce que la spécification C# comporte une règle spéciale pour l’affectation composée qui vous permet d’omettre la conversion explicite.Dans la mission composée x op= y la règle est :

si l'opérateur sélectionné est un opérateur prédéfini, si le type de retour de l'opérateur sélectionné est explicitement convertible en type de x, et si y est implicitement convertible en type de x ou si l'opérateur est un opérateur de décalage, alors l'opération est évaluée comme x = (T)(x op y), où T est le type de x, sauf que x n'est évalué qu'une seule fois.

Malheureusement, votre seul recours est de procéder comme vous l’avez fait.Il n'y a pas de suffixe pour marquer le littéral comme un octet.Le | L'opérateur ne prévoit pas de conversion implicite comme une affectation (c'est-à-direinitialisation) le ferait.

Apparemment, la règle d'expression | 0x80 'Renvoie un int même si vous définissez 0x80 comme' const octet 0x80 '.

Je pense que la règle est que des nombres comme 0x80 sont par défaut int, sauf si vous incluez un suffixe littéral.Alors pour l'expression rule | 0x80, le résultat sera un int puisque 0x80 est un int et que la règle (qui est un octet) peut être convertie en toute sécurité en int.

Selon le standard C, les octets sont TOUJOURS promus en int dans les expressions, même les constantes.Cependant, tant que les deux valeurs sont NON SIGNÉES, les bits de poids fort seront ignorés et l'opération devrait donc renvoyer la valeur correcte.

De même, les flotteurs favorisent le double, etc.

Extraire d'une copie de K&R.Tout est là-dedans.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top