Почему десятичные числа c # не могут быть инициализированы без суффикса M? - PullRequest
35 голосов
/ 04 августа 2011
public class MyClass
{
    public const Decimal CONSTANT = 0.50; // ERROR CS0664   
}

выдает эту ошибку:

ошибка CS0664: Литерал типа double не может быть неявно преобразован в тип 'decimal';используйте суффикс 'M' для создания литерала этого типа

как документированного .Но это работает:

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

И мне интересно, почему они запрещают первый.Мне кажется странным.

Ответы [ 6 ]

47 голосов
/ 04 августа 2011

Тип литерала без суффикс m равен double - это так просто.Вы также не можете инициализировать float таким способом:

float x = 10.0; // Fail

Тип литерала должен быть понятен из самого литерала, а тип переменной, которой он назначен, должен быть назначен на с тип этого литерала.Итак, ваш второй пример работает, потому что есть неявное преобразование из int (тип литерала) в decimal.Не существует неявного преобразования из double в decimal (поскольку это может привести к потере информации).

Лично я бы предпочел его, если бы было нет по умолчанию или если бы по умолчаниюбыл decimal, но это другое дело ...

11 голосов
/ 04 августа 2011

Первый пример - двойной литерал.Второй пример - целочисленный литерал.

Я думаю, что невозможно преобразовать double в десятичное без возможной потери точности, но с целым числом все в порядке.Таким образом, они допускают неявное преобразование с целым числом.

5 голосов
/ 04 августа 2011

Ваш ответ немного ниже по той же ссылке, что и вы, также Здесь . В конверсиях:

«Целочисленные типы неявно преобразуются в десятичную, а результат оценивается как десятичная. Поэтому вы можете инициализировать десятичную переменную, используя целочисленный литерал без суффикса».

Итак, причина в неявном преобразовании между int и decimal. А так как 0.50 рассматривается как двойной, и не существует неявного преобразования между двойным и десятичным, вы получаете ошибку.

Для более подробной информации:

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

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

5 голосов
/ 04 августа 2011

Каждый литерал рассматривается как тип. Если вы не выбрали суффикс 'M', он будет считаться double. То, что вы не можете неявно преобразовать double в decimal, вполне понятно, так как теряет точность.

4 голосов
/ 04 августа 2011

Это выбор дизайна, который сделали создатели C #.

Вероятно, это связано с тем, что double может потерять точность, и они не хотели, чтобы вы хранили эту потерю. int такой проблемы нет.

3 голосов
/ 04 августа 2011

С http://msdn.microsoft.com/en-us/library/364x0z75.aspx: Не существует неявного преобразования между типами с плавающей точкой и десятичным типом; поэтому для преобразования между этими двумя типами необходимо использовать приведение.

Они делают это, потому что double имеет такой огромный диапазон от ± 5,0 × 10– 324 до ± 1,7 × 10 308 , тогда как int составляет всего от -2 147 483 648 до 2 147 483 647. Диапазон десятичного числа (от -7,9 x 10 28 до 7,9 x 10 28 ) / (от 10 0 до 28 ), поэтому он может содержать целое число, но не двойной.

...