web-dev-qa-db-fra.com

Pourquoi les décimales c # ne peuvent-elles pas être initialisées sans le suffixe M?

public class MyClass
{
    public const Decimal CONSTANT = 0.50; // ERROR CS0664   
}

produit cette erreur:

erreur CS0664: le littéral de type double ne peut pas être implicitement converti en type 'décimal'; utiliser un suffixe "M" pour créer un littéral de ce type

comme documenté . Mais cela fonctionne:

public class MyClass
{
    public const Decimal CONSTANT = 50; // OK   
}

Et je me demande pourquoi ils interdisent le premier. Cela me semble bizarre.

35
onof

Le type d'un littéral sans le suffixe m est double - c'est aussi simple que cela. Vous ne pouvez pas non plus initialiser un float de cette façon:

float x = 10.0; // Fail

Le type du littéral doit être indiqué clairement à partir du littéral lui-même, et le type de variable auquel il est affecté doit être attribuable à de le type de ce littéral. Votre deuxième exemple fonctionne donc car il y a une conversion implicite de int (le type du littéral) en decimal. Il n'y a pas de conversion implicite de double vers decimal (car cela peut perdre des informations).

Personnellement, j'aurais préféré qu'il y ait eu non par défaut ou si la valeur par défaut avait été decimal, mais c'est une autre affaire ...

47
Jon Skeet

Le premier exemple est un double littéral. Le deuxième exemple est un littéral entier.

Je suppose qu'il n'est pas possible de convertir le double en décimal sans perte possible de précision, mais c'est correct avec un entier. Ils permettent donc une conversion implicite avec un entier.

11
James Johnston

Chaque littéral est traité comme un type. Si vous ne choisissez pas le suffixe "M", il est traité comme un double. Que vous ne pouvez pas implicitement convertir un double en decimal est tout à fait compréhensible car il perd en précision.

5
Oskar Kjellin

Votre réponse est un peu plus bas dans le même lien que vous avez fourni, également ici . Dans les conversions:

"Les types intégraux sont implicitement convertis en décimaux et le résultat est évalué en décimal. Par conséquent, vous pouvez initialiser une variable décimale à l'aide d'un littéral entier, sans le suffixe".

Donc, la raison est à cause de la conversion implicite entre int et décimal. Et comme 0,50 est traité comme double et qu'il n'y a pas de conversion implicite entre double et décimal, vous obtenez votre erreur.

Pour plus de détails:

http://msdn.Microsoft.com/en-us/library/y5b434w4 (v = vs.80) .aspx

http://msdn.Microsoft.com/en-us/library/yht2cx7b.aspx

5
AJC

C'est un choix de conception que les créateurs de C # ont fait.

Il est probable que double peut perdre de la précision et ils ne voulaient pas que vous stockiez cette perte. int n'ont pas ce problème.

4
Daniel A. White

De http://msdn.Microsoft.com/en-us/library/364x0z75.aspx : Il n'y a pas de conversion implicite entre les types à virgule flottante et le type décimal; par conséquent, une conversion doit être utilisée pour convertir entre ces deux types.

Ils le font parce que le double a une telle étendue ± 5,0 × 10−324 à ± 1,7 × 10308 alors que int n'est que de -2 147 483 648 à 2 147 483 647. La plage d'une décimale est (-7,9 x 1028 à 7,9 x 1028)/(dix0 à 28) afin qu'il puisse contenir un int mais pas un double.

3
Paul