数字文字后面的 C# 后缀

C# suffix behind numeric literal

我是 C# 新手,想了解值的工作原理。如果我看一个普通的整数值,它有 3 个重要部分:类型、名称和值。

int testInt = 3;
 |    |       |
Type Name   Value

但是当我看到一个浮点值时,由于后缀 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 所说的文字。据我了解, "literals" 是包含数字的值类型。但是我不明白的是,为什么这个ulong即使没有后缀也能工作?

ulong bigOne = 2985825802805280508;

然后我尝试了一些不同的东西来理解后缀的重要性

byte testLong = 12312UL;

这没有用,因为字节 (254) 的值太高,后缀不会将其转换为长变量。

为什么第一个词(类型)不足以进行声明?第一个词应该足以说明类型。始终为值添加后缀是最佳做法吗?

存在其他声明变量而不在名称前指定类型的方法:

var myNumber = 10;

在这种情况下,变量类型将由文字值定义。

如果您使用类型 (double|float|int|...) 而不是 "var",编译器会将文字值转换为变量类型(如果可能)。

因此,我认为当您使用 "var" 声明变量时,后缀很重要,并且当不使用后缀时,文字值类型不是默认关联的;

使用后缀太有用还有另一个原因,比如你想在表达式中进行隐式转换的情况。

你在这里混淆了两个不同的东西:

float testFloat = 3.0F;

float 告诉编译器变量 testFloat 将是一个浮点值。 F 告诉编译器 文字 3.0float。编译器需要知道这两个部分,然后才能决定是否可以在不进行转换或隐式转换的情况下将文字分配给变量。

例如,您可以这样做:

float testFloat = 3;

没关系。因为编译器会将 3 视为文字整数,但它知道它可以将其分配给浮点数而不损失精度(这是隐式转换)。但是如果你这样做:

float testFloat = 3.0;

3.0 是文字双精度数(因为这是没有后缀的默认值)并且它不能隐式(即自动)将双精度数转换为浮点数,因为浮点数的精度较低。换句话说,信息 可能会 丢失。所以你要么告诉编译器它是一个文字浮点数:

float testFloat = 3.0f;

或者您通过使用 显式 转换告诉它您可以接受任何精度损失:

float testFloat = (float)3.0;

All1 表达式需要可解析为类型。所以表达式 42 always 需要 exactly 一种类型(恰好是 int)。如果将它分配给 int 变量,则它不能是 int;如果将它分配给 double,则它不能是 double。使用表达式的上下文永远不会1 用于确定它解析为什么类型。

这就是数字文字可以有后缀的原因;这是一种在那个表达式.

中定义那个表达式的类型的方法

请注意,许多数值类型之间也存在隐式转换,因此如果您编写 double d = 42; 表达式 42 实际上是一个整数 ,但是有一个正在对其执行的隐式转换运算符,它将在赋值之前将其转换为 double

1 这里有一些例外,例如 lambda,表达式的类型取决于它的使用方式和方法组;在真空中,这些表达式没有类型。