типизация - типы данных c#




Суффикс C#за числовым литералом (2)

Я новичок в C # и хочу понять, как работают ценности. Если я посмотрю на нормальное целочисленное значение, в нем есть 3 важные части: тип, имя и значение.

int testInt = 3;
 |    |       |
Type Name   Value

Но когда я вижу значение float, это меня немного путает из-за суффикса F

float testFloat = 3.0F;
  |      |        |  |
 Type   Name  Value Type

Теперь в нем есть два типа, и без суффикса F значение будет двойным. Но почему это происходит, когда я могу объявить двойную переменную с

double testDouble = 3.0D;

double как первого слова должно быть достаточно, не так ли? То же самое относится к десятичному значению с суффиксом M:

decimal testDecimal = 3.0M;

Тогда это начинает меня смущать, когда дело доходит до других суффиксов:

ulong bigOne = 2985825802805280508UL;

Я использовал ulong в тесте раньше и знаю, что u для «unsigned» и позволяет значение в два раза выше, чем обычно. Затем вы получаете U снова как суффикс, а L - буквально, как сказал google. Насколько я понимаю, «литералы» - это типы значений, которые содержат числа. Но я не понимаю, почему этот улунг работает даже без суффикса?

ulong bigOne = 2985825802805280508;

Затем я попробовал что-то другое, чтобы понять важность суффикса

byte testLong = 12312UL;

Это не сработало, потому что значение слишком велико для байта (254), и суффикс не преобразует его в длинную переменную.

Почему не первое слово (тип) недостаточно для объявления? Первое слово должно быть достаточно, чтобы указать тип. Лучше ли всегда давать значения суффикс?


Все 1 выражения должны быть разрешимы для типа. Таким образом, выражение 42 всегда должно иметь ровно один тип (это, как правило, int ). Это не может быть int если вы назначаете его переменной int и double если вы назначаете ее double . Контекст, в котором используется выражение, никогда не используется для определения того, к какому типу он решает.

Вот почему числовые литералы могут иметь суффиксы; это способ определения типа этого выражения в этом выражении .

Обратите внимание, что есть также неявные преобразования между многими числовыми типами, поэтому, если вы пишете double d = 42; выражение 42 на самом деле является целым числом , но на нем выполняется оператор неявного преобразования, который преобразует его в double перед назначением.

1 Здесь есть несколько исключений, таких как лямбда, для которых тип выражения зависит от того, как он используется, и групп методов; в вакууме эти выражения не имеют типа.


Здесь вы смешиваете две разные вещи:

float testFloat = 3.0F;

float сообщает компилятору, что переменная testFloat wil является значением с плавающей запятой. F сообщает компилятору, что литерал 3.0 является float . Компилятор должен знать обе части, прежде чем он сможет решить, может ли он назначить литерал переменной без преобразования или неявного преобразования.

Например, вы можете сделать это:

float testFloat = 3;

И это нормально. Поскольку компилятор увидит 3 как целое число буквально, но он знает, что он может назначить это поплавку без потери точности (это неявное преобразование). Но если вы это сделаете:

float testFloat = 3.0;

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

float testFloat = 3.0f;

Или вы говорите, что вы в порядке с любой потерей точности, используя явный приведение:

float testFloat = (float)3.0;




variable-declaration