Подтвердить что ты не робот

Почему двоичные числа С# не могут быть инициализированы без суффикса M?

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

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

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

как документально. Но это работает:

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

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

4b9b3361

Ответ 1

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

float x = 10.0; // Fail

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

Подробнее:

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

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

Ответ 5

Его выбор дизайна, созданный создателями С#.

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

Ответ 6

От 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), поэтому он может содержать int но не двойной.