C# 是一种强类型语言。 这意味着我们必须声明一个变量的类型,该类型指示它将存储的值的类型,例如整数、浮点数、小数点、文本等。
下面声明并初始化了不同数据类型的变量。
int num = 100;
float rate = 10.2f; //浮点型要加 f
double a = 10.01d;// 双精度浮点型 加d
decimal amount = 100.50M; //decimal 固定要加m
char code = 'C';
bool isValid = true;
string name = "Steve";
DateTime dateTime = DateTime.Now;
C#主要将数据类型分为两种类型:值类型和引用类型。 值类型包括简单类型(如 int、float、bool 和 char)、枚举类型、结构类型和 Nullable 值类型。 引用类型包括类类型、接口类型、委托类型和数组类型。 在下一章中详细了解值类型和引用类型。
类型 | .net 对应的类型 | 描述 | 范围 | 默认值 |
---|---|---|---|---|
bool | 布尔值 | True 或 False | False | |
byte | 8 位无符号整数 | 0 到 255 | 0 | |
char | 16 位 Unicode 字符 | U +0000 到 U +ffff | '\0' | |
decimal | 128 位精确的十进制值,28-29 有效位数 | (-7.9 x 1028 到 7.9 x 1028) / 100 到 28 | 0.0M | |
double | 64 位双精度浮点型 | (+/-)5.0 x 10-324 到 (+/-)1.7 x 10308 | 0.0D | |
float | 32 位单精度浮点型 | -3.4 x 1038 到 + 3.4 x 1038 | 0.0F | |
int | 2 位有符号整数类型 | -2,147,483,648 到 2,147,483,647 | 0 | |
long | 64 位有符号整数类型 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 0L | |
sbyte | 8 位有符号整数类型 | -128 到 127 | 0 | |
short | 16 位有符号整数类型 | -32,768 到 32,767 | 0 | |
uint | 32 位无符号整数类型 | 0 到 4,294,967,295 | 0 | |
ulong | 64 位无符号整数类型 | 0 到 18,446,744,073,709,551,615 | 0 | |
ushort | 16 位无符号整数类型 | 0 到 65,535 | 0 | |
DateTime | 时间 |
类型 | 描述 | 范围 | 默认值 |
---|---|---|---|
object | 所有类型的基类型 | null | |
string | 字符串,(表现行为类似于值类型) | null |
正如你在上表中看到的,每种数据类型(字符串和对象除外)都包含取值范围。 如果值超出数据类型的允许范围,编译器将给出错误。 例如,int 数据类型的范围是 -2,147,483,648 到 2,147,483,647。 因此,如果您分配的值不在此范围内,则编译器会出错。
int i = 21474836470; //无法将类型“long”隐式转换为“int”。存在一个显式转换(是否缺少强制转换?)
// compile time error: Cannot implicitly convert type 'long' to 'int'.
无符号整数、long、float、double 和decimal 类型的值必须分别以u、l、f、d 和m 为后缀。
uint ui = 100u;
float fl = 10.2f;
long l = 45755452222222l;
ulong ul = 45755452222222ul;
double d = 11452222.555d;
decimal mon = 1000.15m;
预定义的这些数据类型是其 .NET 类型(CLR 类)名称的别名。 下表列出了预定义数据类型和相关 .NET 类名的别名。
别名 | .NET 类型 | 类别 |
---|---|---|
byte | System.Byte | struct |
sbyte | System.SByte | struct |
int | System.Int32 | struct |
uint | System.UInt32 | struct |
short | System.Int16 | struct |
ushort | System.UInt16 | struct |
long | System.Int64 | struct |
ulong | System.UInt64 | struct |
float | System.Single | struct |
double | System.Double | struct |
char | System.Char | struct |
bool | System.Boolean | struct |
object | System.Object | Class |
string | System.String | Class |
decimal | System.Decimal | struct |
DateTime | System.DateTime | struct |
这意味着无论你定义一个 int 还是 Int32 的变量,两者都是一样的。
int i = 345;
Int32 i = 345;// 跟上面的是一样
每个数据类型都有一个默认值。 数字类型为 0,boolean 为 false,char 的默认值为 '\0'。 使用 default(typename) 分配数据类型的默认值或 C# 7.1 以后,使用default。
int i = default(int); // 0
DateTime d = default(DateTime); //0001/1/1 00:00:00
object o = default(object); //null;
string s = default(string); //null
// C# 7.1 以后我们可以用如下的方法。(方法调用里面也可以直接用)
int i2 = default;
DateTime d2 = default;
类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型。在 C# 中,类型铸造有两种形式:
int i = 345;
float f = i;
Console.WriteLine(f); //output: 345
从 int、uint、long 或 ulong 到 float 以及从 long 或 ulong 到 double 的转换可能会导致精度损失。 没有数据类型隐式转换为 char 类型。
可能造成数据丢失的都需要强制转换 比如从 int 到 byte (值的范围变小了)
int i = 214748;
byte b = (byte)i; //b 变成了220
上面的显示转换,在值太大的情况下也会转换成功,这个有时候可能是我们所不希望的。我们希望在值超出范围的情况下抛出异常,则我们可以使用 使用System.Convert类来进行转换
var b2 = Convert.ToInt16(int.MaxValue);//会抛出 OverflowException
想转化成float就得用 Convert.ToSingle(i); //方法名用的是 .Net 库里的名字。而不是 ToFloat()
Convert类里面有很多重载。string 类也是可以转化成 int
var s ="4456";
var i = Convert.ToInt32(s); // i 是4456
这个在我们程序里面是经常要处理的事情。 第个类型里面基本上都有一个Parse 或者 TryParse
if (int.TryParse("65", out int age))
{
//age 是 65
};