总目录
前言
本文为C# 数据类型 其中的一个章节,主要介绍C# 的内置 值类型。
一、内置值类型是什么?
-
C# 提供的内置值类型,也称为"简单类型",所有简单值都是结构类型。
-
它们与其他结构类型的不同之处在于,它们允许特定的附加操作:
- 可以使用文字为简单类型提供值。
- 例如,
'A'
是 char类型的文本,2001
是 int 类型的文本,12.34m
是 decimal类型的文本。
- 例如,
- 可以使用
const
关键字声明简单类型的常量。- 例如,可以定义 const decimal = 12.34m。不能具有其他结构类型的常数。
- 常量表达式的操作数都是简单类型的常量,在编译时进行计算。
- 可以使用文字为简单类型提供值。
有不理解的 内置类型,结构类型等概念 请 查阅C# 数据类型
二、内置值类型有哪些?
- 整型
- 浮点型
- 布尔型(bool),表示布尔值
- 字符型(char),表示 Unicode UTF-16 字符
C# 提供了一组标准的内置类型, 这些类型可供在任何 C# 程序中使用。
内置类型其实就是.NET类型 在C# 中的别名,为了方便C#的编程。
三、内置值类型的使用?
1. 整型
1)基础介绍
- 整型类型 表示整数。 所有的整型类型均为值类型。
- 它们还是简单类型,可以使用文本进行初始化。
- 所有整型类型都支持算术、位、逻辑、比较和相等运算符。
- 每个整型数值类型的默认值 都是
零
。 - 每个整型类型都有
MinValue
和MaxValue
属性,提供该类型的最小值和最大值。 这些属性是编译时常量,但本机大小类型(nint 和 nuint)的情况除外。 对于本地大小的类型,MinValue 和 MaxValue 属性是在运行时计算的。 这些类型的大小取决于进程设置。
在除最后两行之外的所有表行中,最左侧列中的每个 C# 类型关键字都是相应 .NET 类型的别名。 关键字和 .NET 类型名称是可互换的。 例如,以下声明声明了相同类型的变量:
csharp
int a = 123;
System.Int32 b = 123;
表的最后两行中的 nint 和 nuint 类型是本机大小的整数。 可以使用 nint 和 nuint 上下文关键字定义原本大小的整数。 在 32 位进程中运行时有 32 位的整数,在 64 位进程中运行时有 64 位的整数。 这些类型可用于互操作方案、低级别的库,可用于在广泛使用整数运算的方案中提高性能。
本机大小的整数类型在内部表示为 .NET 类型 System.IntPtr 和 System.UIntPtr。 从 C# 11 开始,nint 和 nuint 类型是基础类型的别名。
2)BigInteger 扩展
- 除以上整型 类型的外,还有一个
System.Numerics.BigInteger
结构用于表示没有上限或下限的带符号整数。 - BigInteger 虽然是 结构,但是用来表示整数。
- 详见 C# BigInteger 的使用
3)整数文本的前缀
- C# 中各种进制数值的文本表示方式
- 二进制,使用 0b 或 0B 前缀
- 八进制,C# 中没有八进制的表示方法
- 十进制,不使用任何前缀
- 十六进制,使用 0x 或 0X 前缀
csharp
//合法的二进制
int a = 0b101; //换算成十进制为 5
int b = 0B100001; //换算成十进制为 33
Console.WriteLine(a); //5
Console.WriteLine(b); //33
//非法的二进制
int c = 101010; //无前缀 0B,相当于十进制
int d = 0B410; //4不是有效的二进制数字
csharp
//合法的十六进制
int a = 0X2A; //换算成十进制为 42
int b = -0XA0; //换算成十进制为 -160
int c = 0xffff; //换算成十进制为 65535
Console.WriteLine(a);// 42
Console.WriteLine(b);// -160
//非法的十六进制
int m = 5A; //没有前缀 0X,是一个无效数字
int n = 0X3H; //H不是有效的十六进制数字
为啥要适用0b 或0x等前缀来表示不同进制的数值呢?道理很简单,就比如说我写个数字111 要是我不告诉你他是什么进制的,你如何知道该数字真实表示的值呢?有了前缀我们就能更明确的知道该数字实际的值。
4)整数文本的后缀
csharp
static void Main(string[] args)
{
var value1 = 12_1000_0000_0000u;
Console.WriteLine(value1.GetType()); // System.UInt64
var value2 = 121u;
Console.WriteLine(value2.GetType()); // System.UInt32
}
- 整数文本的类型由其后缀确定
- 如果文本没有后缀,则自动进行类型推断,其类型为以下类型中可表示其值的第一个类型:int、uint、long、ulong。
- 如果文本以 U 或 u 为后缀,则其类型为以下类型中可表示其值的第一个类型:uint、ulong。
- 如果文本以 L 或 l 为后缀,则其类型为以下类型中可表示其值的第一个类型:long、ulong。
- 如果文本的后缀为 UL、Ul、uL、ul、LU、Lu、lU 或 lu,则其类型为 ulong。
5)转换
可以将任何整型数值类型转换为其他整数数值类型。 如果目标类型可以存储源类型的所有值,则转换是隐式的。 否则,需要使用强制转换表达式来执行显式转换。
csharp
double x = 1234.7;
int a = (int)x;
Console.WriteLine(a); // output: 1234
形如:(int)x
的就是 强制转换表达式
6)本机大小的整数
本机大小的整数类型具有特殊行为,因为存储是由目标计算机上的自然整数大小决定的。
- 若要在运行时获取本机大小的整数大小,可以使用
sizeof()
。 但是,必须在不安全的上下文中编译代码。- 也可以通过静态
IntPtr.Size
和UIntPtr.Size
属性获得等效的值。
- 也可以通过静态
csharp
static void Main(string[] args)
{
unsafe
{
Console.WriteLine($"size of nint = {sizeof(nint)}");
Console.WriteLine($"size of nuint = {sizeof(nuint)}");
}
Console.WriteLine($"size of nint = {IntPtr.Size}");
Console.WriteLine($"size of nuint = {UIntPtr.Size}");
// output when run in a 64-bit process
//size of nint = 8
//size of nuint = 8
// output when run in a 32-bit process
//size of nint = 4
//size of nuint = 4
}
注意:使用unsafe
需要在 .csproj
项目文件中,新增如下配置:
- 若要在运行时获取本机大小的整数的最小值和最大值,请将 MinValue 和 MaxValue 用作 nint 和 nuint 关键字的静态属性,如以下示例中所示:
csharp
Console.WriteLine($"nint.MinValue = {nint.MinValue}");
Console.WriteLine($"nint.MaxValue = {nint.MaxValue}");
Console.WriteLine($"nuint.MinValue = {nuint.MinValue}");
Console.WriteLine($"nuint.MaxValue = {nuint.MaxValue}");
// output when run in a 64-bit process
//nint.MinValue = -9223372036854775808
//nint.MaxValue = 9223372036854775807
//nuint.MinValue = 0
//nuint.MaxValue = 18446744073709551615
// output when run in a 32-bit process
//nint.MinValue = -2147483648
//nint.MaxValue = 2147483647
//nuint.MinValue = 0
//nuint.MaxValue = 4294967295
- 可以使用以下范围内的常量值:
- 对于 nint:Int32.MinValue 到 Int32.MaxValue。
- 对于 nuint:UInt32.MinValue 到 UInt32.MaxValue。
关于以上这些数据的数据范围的原理,可查阅:C# 整型、浮点型 数值范围原理分析
2. 浮点型
1)基础介绍
- 浮点数值类型表示实数。 所有浮点型数值类型均为值类型。
- 它们还是简单类型,可以使用文本进行初始化。
- 所有浮点数值类型都支持算术、比较和相等运算符。
- 每个浮点类型的默认值都为
零
- 每个浮点类型都有
MinValue
和MaxValue
常量,提供该类型的最小值和最大有限值。 float
anddouble
类型还提供可表示非数字和无穷大值的常量。- 例如,double 类型提供以下常量:Double.NaN(非数字)、Double.NegativeInfinity(负无穷大值) 和 Double.PositiveInfinity(正无穷大值)。
在上表中,最左侧列中的每个 C# 类型关键字都是相应 .NET 类型的别名。 它们是可互换的。 例如,以下声明声明了相同类型的变量:
csharp
double a = 12.3;
System.Double b = 12.3;
2)浮点类型的使用
- 可在表达式中将整型类型与 float 和 double 类型混合使用。
- 可在表达式中混合使用整型类型和 decimal 类型。
- 不能在表达式中将 decimal 类型与 float 和 double 类型混合使用。
csharp
static void Main(string[] args)
{
double a = 1.0;
decimal b = 2.1m;
Console.WriteLine(a + (double)b);
Console.WriteLine((decimal)a + b);
}
- 如果需要高速度和较小内存占用,并且可以接受一定的精度损失,选择 float。
- 如果需要更高的精度和更大的数值范围,但仍然可以接受浮点数的舍入误差,选择 double。
- 如果需要绝对精确的小数运算,特别是涉及货币和金融应用,选择 decimal。
3) NaN、NegativeInfinity、PositiveInfinity
以 Double 为例:
-
Double.NaN 表示不是数字 (NaN) 的值。 此字段为常量。
-
当我们需要判断一个值 是否是 Double.NaN的时候,需要使用 Double.IsNaN方法,而非
==
,具体原因如下例所示:
csharp
static void Main(string[] args)
{
double zero = 0;
var res = 0 / zero;
Console.WriteLine($"{res} - {res.GetType()}"); // NaN - System.Double
var result1 = Double.IsNaN(res);
var result2 = res == double.NaN;
Console.WriteLine($"{result1}-{result2}"); // True - False
}
- Double.NegativeInfinity表示负无穷,此字段为常量。
- 此常量的值是将负数除以零的结果。
- 当操作的结果小于 Double.MinValue时,将返回此常量。
- 用于 IsNegativeInfinity 确定值的计算结果是否为负无穷大。
csharp
// This will equal Infinity.
Console.WriteLine("10.0 minus NegativeInfinity equals {0}.", (10.0 - Double.NegativeInfinity).ToString());
//10.0 minus NegativeInfinity equals ∞.
- Double.PositiveInfinity 表示正无穷,此字段为常量。
- 此常量的值是将正数除以零的结果。
- 当操作的结果大于 Double.MaxValue时,将返回此常量。
- 使用 IsPositiveInfinity 确定值的计算结果是否为正无穷大。
csharp
// This will equal Infinity.
Console.WriteLine("PositiveInfinity plus 10.0 equals {0}.", (Double.PositiveInfinity + 10.0).ToString());
// PositiveInfinity plus 10.0 equals ∞.
4)浮点文本的后缀
各浮点型数据类型表示方式:
- 不带后缀的文本或带有 d 或 D 后缀的文本的类型为 double
- 带有 f 或 F 后缀的文本的类型为 float
- 带有 m 或 M 后缀的文本的类型为 decimal
csharp
double d = 3D;
d = 4d;
d = 3.934_001;
float f = 3_000.5F;
f = 5.4f;
decimal myMoney = 3_000.5m;
myMoney = 400.75M;
还可以使用科学记数法,即指定真实文本的指数部分,如以下示例所示:
csharp
double d = 0.42e2;
Console.WriteLine(d); // output 42
float f = 134.45E-2f;
Console.WriteLine(f); // output: 1.3445
decimal m = 1.5E6m;
Console.WriteLine(m); // output: 1500000
5)转换
浮点数值类型之间只有一种隐式转换:从 float 到 double。 但是,可以使用显式强制转换将任何浮点类型转换为任何其他浮点类型。
3. 布尔型
1)基本介绍
- bool 类型关键字是 .NET System.Boolean 结构类型的别名,它表示一个布尔值,可为 true 或 false。
- bool 类型是 比较和相等运算符的结果类型。 bool 表达式可以是 if、do、while 和 for 语句中以及
条件运算符 ?:
中的控制条件表达式。 - bool 类型的默认值为
false
。
csharp
bool check = true;
Console.WriteLine(check ? "Checked" : "Not checked"); // output: Checked
Console.WriteLine(false ? "Checked" : "Not checked"); // output: Not checked
2)转换
true 转为整型对应的就是 1 ,反之,false 对应的 0
csharp
static void Main(string[] args)
{
bool b1 = true;
bool b2 = false;
Console.WriteLine($"true=>{Convert.ToInt32(b1)} - false=>{Convert.ToInt32(b2)}");
//true=>1 - false=>0
}
3) FalseString、TrueString
csharp
static void Main(string[] args)
{
Console.WriteLine($"{Boolean.FalseString} - {Boolean.TrueString}");
// False - True
}
4. 字符型
1) 基本介绍
- char 类型关键字是 .NET System.Char 结构类型的别名,它表示 Unicode UTF-16 字符。
- char 类型的默认值为 \0,即 U+0000。
- char 类型支持比较、相等、增量和减量运算符。 此外,对于 char 操作数,算数和逻辑位运算符对相应的字符代码执行操作,并得出 int 类型的结果。
2) 字符文本
可以使用以下命令指定 char 值:
- 字符文本。
- Unicode 转义序列,它是 \u 后跟字符代码的十六进制表示形式(四个符号)。
- 十六进制转义序列,它是 \x 后跟字符代码的十六进制表示形式。
csharp
var chars = new[]
{
'j',
'\u006A',
'\x006A',
(char)106,
};
Console.WriteLine(string.Join(" ", chars)); // output: j j j j
3)转换
- char 类型可隐式转换为以下整型类型:ushort、int、uint、long 和 ulong。
- 它也可以隐式转换为内置浮点数值类型:float、double 和 decimal。
- 它可以显式转换为 sbyte、byte 和 short 整型类型。
- 无法将其他类型隐式转换为 char 类型。 但是,任何整型或浮点数值类型都可显式转换为 char。
结语
回到目录页:C# 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。
参考资料:
C# 类型系统
强制转换和类型转换(C# 编程指南)
值类型(C# 参考)
8 种类型
不安全代码、指针类型和函数指针
官方 - C#文档
官方 - .NET 文档