开放的编程资料库

当前位置:我爱分享网 > C#教程 > 正文

C# 数据类型

在这篇文章中,我们讨论了C#中的数据类型。

计算机程序(包括电子表格、文本编辑器、计算器或聊天客户端)处理数据。处理各种数据类型的工具是现代计算机语言的重要组成部分。数据类型是一组值和对这些值的允许操作。

C#数据类型

数据类型是一组值,以及对这些值的允许操作。

C#中的两种基本数据类型是值类型和引用类型。基本类型(字符串除外)、枚举、元组和结构都是值类型。类、记录、字符串、接口、数组和委托都是引用类型。每种类型都有一个默认值。

引用类型是在堆上创建的。引用类型的生命周期由.NET框架管理。引用类型的默认值是空引用。对引用类型的变量赋值会创建引用的副本,而不是引用值的副本。

值类型是在堆栈上创建的。生命周期由变量的生命周期决定。对值类型的变量赋值会创建所赋值的副本。值类型具有不同的默认值。例如,布尔默认值为false,十进制为0,string为空字符串“”。

C#布尔值

bool数据类型是具有两个值之一的原始数据类型:truefalse

我们要为新生儿取名。如果是男孩,我们选择约翰。如果是女孩,我们会选择Victoria。

var random = new Random();

bool male = Convert.ToBoolean(random.Next(0, 2));

if (male)
{
    Console.WriteLine("We will use name John");
}
else
{
    Console.WriteLine("We will use name Victoria");
}

该程序使用随机数生成器来模拟我们的案例。

var random = new Random();

我们创建了一个用于计算随机数的Random对象。它是System命名空间的一部分。

bool male = Convert.ToBoolean(random.Next(0, 2));

Next方法返回指定范围内的随机数。包括下限,不包括上限。换句话说,我们接收到0或1。稍后Convert方法将这些值转换为布尔值,0为false,1为true。

if (male)
{
    Console.WriteLine("We will use name John");
} else
{
    Console.WriteLine("We will use name Victoria");
}

如果male变量设置为true,我们选择名字John。否则,我们选择Victoria这个名字。if/else语句等控制结构使用布尔值。

$ dotnet run
We will use name John
$ dotnet run
We will use name John
$ dotnet run
We will use name Victoria

C#整数

整数是实数的子集。它们是在没有小数部分的情况下编写的。整数属于集合Z={…,-2,-1,0,1,2,…}。整数是无限的。

在计算机语言中,整数是原始数据类型。计算机实际上只能处理整数值的子集,因为计算机的容量是有限的。整数用于计算离散实体。我们可以有3、4、6个人类,但我们不能有3.33个人类。我们可以有3.33公斤。

VB别名 .NET类型 大小 范围
sbyte System.SByte 1字节 -128到127
byte System.Byte 1字节 0到255
System.Int16 2字节 -32768到32767
ushort System.UInt16 2字节 0到65,535
int System.Int32 4字节 -2,147,483,648到2,147,483,647
uint System.UInt32 4字节 0到4,294,967,295
long System.Int64 8字节 -9,223,372,036,854,775,808到9,223,372,036,854,775,807
ulong System.UInt64 8字节 0到18,446,744,073,709,551,615

这些整数类型可以根据我们的需要使用。没有人(也许除了一些圣经人物)可以超过120岁、130岁。然后我们可以在程序中使用byte类型作为age变量。这将节省一些内存。

离散实体

如果我们处理整数,我们处理的是离散实体。我们会用整数来数苹果。

int baskets = 16;
int applesInBasket = 24;

int total = baskets * applesInBasket;

Console.WriteLine($"There are total of {total} apples");

在我们的程序中,我们计算苹果的总量。我们使用乘法运算。

int baskets = 16;
int applesInBasket = 24;

篮子的数量和每个篮子里苹果的数量都是整数值。

int total = baskets * applesInBasket;

将这些值相乘我们也得到一个整数。

$ dotnet run
There are total of 384 apples

C#整数表示法

整数可以在C#中用三种不同的表示法指定:十进制、十六进制和二进制。八进制值没有符号。正如我们所知,十进制数通常被使用。十六进制数以0x字符开头,二进制以0b开头。

int num1 = 31;
int num2 = 0x31;
int num3 = 0b1101;

Console.WriteLine(num1);
Console.WriteLine(num2);
Console.WriteLine(num3);

在程序中,我们用三种不同的符号表示三个整数。

$ dotnet run
31
49
13

默认的表示法是小数。程序以非十进制显示这三个数字。

使用下划线

C#允许对数字文字使用下划线字符以提高值的可读性。

var num1 = 234_321_000;
Console.WriteLine(num1);

var num2 = 0b_0110_000_100;
Console.WriteLine(num2);

该程序使用带有下划线字符的整数文字来提高值的可读性。

算术溢出

算术溢出是一种情况,当计算产生的结果的量值大于给定寄存器或存储位置可以存储或表示的结果时发生。

byte a = 254;

Console.WriteLine(a);
a++;

Console.WriteLine(a);
a++;

Console.WriteLine(a);
a++;

Console.WriteLine(a);

在这个例子中,我们尝试分配一个超出数据类型范围的值。这会导致算术溢出。

$ dotnet run
254
255
0
1

当发生溢出时,变量被重置为数据类型的下限。(如果是字节类型,则为零。)

使用checked关键字,我们可以在发生溢出时强制执行异常。

checked
{
    byte a = 254;

    Console.WriteLine(a);
    a++;

    Console.WriteLine(a);
    a++;

    Console.WriteLine(a);
    a++;

    Console.WriteLine(a);
}

在示例中,语句放在checked块的主体中​​。

$ dotnet run
254
255
Unhandled Exception: System.OverflowException: Arithmetic operation resulted in an overflow.
    ...

这次抛出了System.OverflowException

C#浮点数

浮点数在计算中代表实数。实数测量连续的量,如重量、高度或速度。在C#中,我们有三种浮点类型:floatdoubledecimal

/表>

上表给出了浮点类型的特点。

默认情况下,实数在C#程序中是双精度的。要使用不同的类型,我们必须使用后缀。f/f用于float数字,M/m用于decimal数字。

float n1 = 1.234f;
double n2 = 1.234;
decimal n3 = 1.234m;

Console.WriteLine(n1);
Console.WriteLine(n2);
Console.WriteLine(n3);

Console.WriteLine(n1.GetType());
Console.WriteLine(n2.GetType());
Console.WriteLine(n3.GetType());

在上面的程序中,我们对浮点数使用了三种不同的文字表示法。

float n1 = 1.234f;

f后缀用于float数字。

double n2 = 1.234;

如果我们不使用后缀,那么它就是一个double数字。我们可以选择使用d后缀。

Console.WriteLine(n1.GetType());

GetType方法返回数字的类型。

$ dotnet run
1.234
1.234
1.234
System.Single
System.Double
System.Decimal

我们可以使用各种语法来创建浮点值。

float n1 = 1.234f;
float n2 = 1.2e-3f;
float n3 = (float)1 / 3;

Console.WriteLine(n1);
Console.WriteLine(n2);
Console.WriteLine(n3);

我们有三种创建浮点值的方法。第一种是使用小数点的“正常”方式。第二个使用科学记数法。最后一个是数值运算的结果。

float n2 = 1.2e-3f;

这是浮点数的科学计数法。也称为指数表示法,它是一种书写太大或太小而无法方便地用标准十进制表示法书写的数字的方法。

float n3 = (float) 1 / 3;

(float)构造称为转换。除法运算默认返回整数。通过转换我们得到一个浮点数。

$ dotnet run
1.234
0.0012
0.3333333

floatdouble类型不精确。

double n1 = 0.1 + 0.1 + 0.1;
double n2 = 1 / 3.0;

if (n1 == n2)
{
    Console.WriteLine("Numbers are equal");
}
else
{
    Console.WriteLine("Numbers are not equal");
}

比较浮点值时应谨慎。

$ dotnet run
Numbers are not equal

一名100米的短跑运动员跑了9.87秒。他的速度是多少公里/小时?

using System;

float distance = 0.1f;

float time = 9.87f / 3600;

float speed = distance / time;

Console.WriteLine($"The average speed of a sprinter is {speed} km/h");

在这个例子中,需要使用浮点值。

float distance = 0.1f;

100米等于0.1公里。

float time = 9.87f / 3600;

9.87秒是9.87/(60*60)小时。

float speed = distance / time;

为了获得速度,我们将距离除以时间。

$ dotnet run
The average speed of a sprinter is 36.47416 km/h

C#枚举

枚举类型(也称为枚举或枚举)是由一组命名值组成的数据类型。已声明为具有枚举类型的变量可以分配任何枚举数作为值。枚举使代码更具可读性。

Days day = Days.Monday;

if (day == Days.Monday)
{
    Console.WriteLine("It is Monday");
}

Console.WriteLine(day);

foreach (int i in Enum.GetValues(typeof(Days)))
{
    Console.WriteLine(i);
}

enum Days
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

在我们的代码示例中,我们为工作日创建一个枚举。

enum Days
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

枚举是使用enum关键字创建的。Monday,Tuesday,…裸词实际上存储数字0..6。

Days day = Days.Monday;

我们有一个名为day的变量,它是枚举类型Days。它被初始化为星期一。

if (day == Days.Monday)
{
    Console.WriteLine("It is Monday");
}

这段代码比将日期变量与某个数字进行比较更具可读性。

Console.WriteLine(day);

此行将星期一打印到控制台。

foreach (int i in Enum.GetValues(typeof(Days)))
{
    Console.WriteLine(i);
}

此循环将0..6打印到控制台。我们获得了enum值的基础类型。对于计算机,enum只是一个数字。typeof是用于获取类型的System.Type对象的运算符。GetValues方法需要它。此方法返回指定枚举值的数组。foreach关键字逐个元素遍历数组并将它们打印到终端。

我们进一步处理枚举。

Seasons s1 = Seasons.Spring;
Seasons s2 = Seasons.Autumn;

Console.WriteLine(s1);
Console.WriteLine(s2);

public enum Seasons : byte
{
    Spring = 1,
    Summer = 2,
    Autumn = 3,
    Winter = 4
}

季节可以很容易地用作枚举。我们可以为enum指定底层类型,我们可以为它们提供精确的值。

public enum Seasons : byte
{
    Spring = 1,
    Summer = 2,
    Autumn = 3,
    Winter = 4
}

使用冒号和数据类型,我们指定了enum的基础类型。我们还给每个成员一个特定的编号。

Console.WriteLine(s1);
Console.WriteLine(s2);

这两行将enum值打印到控制台。

$ dotnet run
Spring
Autumn

C#元组

元组是有序的、不可变的异构数据值列表。元组是值类型。元组必须至少包含两个元素。元组是用圆括号定义的。

var words = ("sky", "blue", "rock", "fountain");

Console.WriteLine(words);

Console.WriteLine(words.Item1);
Console.WriteLine(words.Item2);

var words2 = (w1: "forest", w2: "deep", w3: "sea");

Console.WriteLine(words2.w1);
Console.WriteLine(words2.w2);
Console.WriteLine(words2.w3);

在示例中我们定义了两个元组。

var words = ("sky", "blue", "rock", "fountain");

这是一个未命名的元组定义。

Console.WriteLine(words);

我们将元组的所有元素打印到控制台。

Console.WriteLine(words.Item1);
Console.WriteLine(words.Item2);

我们打印前两个元素。我们使用特殊的Item1Item2、…属性访问未命名元组的元素。

var words2 = (w1: "forest", w2: "deep", w3: "sea");

这是命名元组的定义。

Console.WriteLine(words2.w1);
Console.WriteLine(words2.w2);
Console.WriteLine(words2.w3);

我们通过名称访问元素。

$ dotnet run
(sky, blue, rock, fountain)
sky
blue
forest
deep
sea

C#记录

C#9引入了记录。记录是不可变的引用类型。记录类型使用基于值的相等性。使用record关键字创建记录。

记录的主要目的是成为数据持有者。

var cars = new List<Car>
{
    new Car("Audi", 52642),
    new Car("Mercedes", 57127),
    new Car("Skoda", 9000),
    new Car("Volvo", 29000),
    new Car("Bentley", 350000),
    new Car("Citroen", 21000),
    new Car("Hummer", 41400),
    new Car("Volkswagen", 21600)
};

var res = from car in cars
          where car.Price > 30000 && car.Price < 100000
          select new { car.Name, car.Price };

foreach (var car in res)
{
    Console.WriteLine($"{car.Name} {car.Price}");
}

record Car(string Name, int Price);

在示例中,我们使用LINQ来筛选汽车对象列表。我们包括价格在30000到100000之间的所有汽车。语言集成查询(LINQ)驻留在System.Linq命名空间中,它包含在隐式使用中。

record Car(string Name, int Price);

汽车是一种记录类型。

$ dotnet run
Audi 52642
Mercedes 57127
Hummer 41400

C#字符串和字符

string是一种数据类型,表示计算机程序中的文本数据。C#中的字符串是Unicode字符序列。char是单个Unicode字符。字符串用双引号括起来。

string word = "ZetCode";

char c = word[0];

Console.WriteLine(c);

程序将'Z'字符打印到终端。

string word = "ZetCode";

这里我们创建了一个字符串变量并为其分配了"ZetCode"值。

char c = word[0];

string是一个Unicode字符数组。我们可以使用arrayaccess表示法从字符串中获取特定字符。方括号内的数字是字符数组的索引。该索引从零开始计数。这意味着第一个字符的索引为0。

$ dotnet run
Z

C#数组

数组是一种处理元素集合的复杂数据类型。每个元素都可以通过索引访问。数组的所有元素必须是相同的数据类型。

int[] numbers = new int[5];

numbers[0] = 3;
numbers[1] = 2;
numbers[2] = 1;
numbers[3] = 5;
numbers[4] = 6;

int len = numbers.Length;

for (int i = 0; i < len; i++)
{
    Console.WriteLine(numbers[i]);
}

在这个例子中,我们声明了一个数组,用数据填充它,然后将数组的内容打印到控制台。

int[] numbers = new int[5];

我们声明了一个整数数组,它最多可以存储五个整数。所以我们有一个包含五个元素的数组,索引为0..4。

numbers[0] = 3;
numbers[1] = 2;
numbers[2] = 1;
numbers[3] = 5;
numbers[4] = 6;

这里我们为创建的数组赋值。我们可以通过数组访问符号来访问数组的元素。它由数组名称后跟方括号组成。在方括号内,我们指定了我们想要的元素的索引。

int len = numbers.Length;

每个数组都有一个Length属性,它返回数组中元素的数量。

for (int i=0; i<len; i++)
{
    Console.WriteLine(numbers[i]);
}

我们遍历数组并将数据打印到控制台。

C#日期时间

DateTime是一个值类型。它代表一个瞬间,通常表示为一天中的日期和时间。

DateTime now = DateTime.Now;

System.Console.WriteLine(now);
System.Console.WriteLine(now.ToShortDateString());
System.Console.WriteLine(now.ToShortTimeString());

我们以三种不同的格式显示今天的日期:日期和时间、日期和时间。

DateTime now = DateTime.Now;

获取一个DateTime对象,该对象设置为此计算机上的当前日期和时间,以本地时间表示。

System.Console.WriteLine(now);

此行以完整格式打印日期。

System.Console.WriteLine(now.ToShortDateString());
System.Console.WriteLine(now.ToShortTimeString());

ToShortDateString返回短日期字符串格式,ToShortTimeString返回短时间字符串格式。

$ dotnet run
11/1/2022 10:26:06 AM
11/1/2022
10:26 AM

C#类型转换

我们经常同时处理多种数据类型。将一种数据类型转换为另一种数据类型是编程中的一项常见工作。类型转换类型转换是指将一种数据类型的实体更改为另一种数据类型。有两种类型的转换:隐式和显式。隐式类型转换,也称为强制转换,是由编译器自动进行的类型转换。

int val1 = 0;
byte val2 = 15;

val1 = val2;

Console.WriteLine(val1.GetType());
Console.WriteLine(val2.GetType());

Console.WriteLine(12 + 12.5);
Console.WriteLine("12" + 12);

在这个例子中,我们有几个隐式转换。

val1 = val2;

这里我们使用两种不同的类型:intbyte。我们将byte值分配给int价值。这是一个扩大的操作。int值有四个字节;字节值只有一个字节。扩大转换是允许的。如果我们想将int分配给byte,这将是一个缩短转换。

C#编译器不允许隐式缩短转换。这是因为在隐式缩短转换中,我们可能会无意中降低精度。我们可以进行缩短转换,但我们必须将其告知编译器。我们知道我们在做什么。可以通过显式转换来完成。

Console.WriteLine(12 + 12.5);

我们添加两个值:一个整数和一个浮点值。结果是浮点值。这是一个扩大的隐式转换。

Console.WriteLine("12" + 12);

结果是1212。​​一个整数被转换成一个字符串,两个字符串被连接起来。

接下来我们展示一些C#中的显式转换。

double b = 13.5;

float a = (float) b;
float c = (int) a;

Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);

我们有三个价值观。我们使用这些值进行一些显式转换。

float a = (float) b;

我们将double值转换为float值。显式转换是通过在两个圆括号之间指定预期类型来完成的。在这种情况下,不会丢失任何精度。数字13.5可以安全地分配给这两种类型。

float c = (int) a;

我们将float值转换为int值。在此声明中,我们放宽了一些精度:13.5变为13。

$ dotnet run
13.5
13.5
13

C#可空类型

值类型不能被分配一个null字面量,引用类型可以。与数据库一起工作的应用程序处理空值。因此,特殊的可空类型被引入到C#语言中。可空类型是System.Nullablestruct的实例。

Nullable<bool> male = null;
int? age = null;

Console.WriteLine(male.HasValue);
Console.WriteLine(age.HasValue);

一个演示可空类型的简单示例。

Nullable<bool> male = null;
int? age = null;

声明可空类型有两种方法。使用Nullable泛型结构,其中类型在尖括号之间指定,或者我们可以在类型后使用问号。后者实际上是第一种表示法的简写。

$ dotnet run
False
False

C#转换和解析方法

有两组方法用于值的转换。

Console.WriteLine(Convert.ToBoolean(0.3));
Console.WriteLine(Convert.ToBoolean(3));
Console.WriteLine(Convert.ToBoolean(0));
Console.WriteLine(Convert.ToBoolean(-1));

Console.WriteLine(Convert.ToInt32("452"));
Console.WriteLine(Convert.ToInt32(34.5));

Convert类有许多用于转换值的方法。我们使用其中两个。

Console.WriteLine(Convert.ToBoolean(0.3));

我们将double值转换为bool值。

Console.WriteLine(Convert.ToInt32("452"));

这里我们将string转换为int

$ dotnet run
True
True
False
True
452
34
Console.WriteLine(int.Parse("34"));
Console.WriteLine(int.Parse("-34"));
Console.WriteLine(int.Parse("+34"));

将字符串转换为整数是一项非常常见的任务。当我们从数据库或GUI组件中获取值时,我们经常会进行此类转换。

Console.WriteLine(int.Parse("34"));

我们使用intParse方法将string转换为int值。

$ dotnet run
34
-34
34

在本文中,我们介绍了C#中的数据类型及其转换。

列出所有C#教程。

未经允许不得转载:我爱分享网 » C# 数据类型

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏
C#别名 .NET类型 大小 精度 范围
float System.Single 4字节 7位 +-1.5×10-45至+-3.4×1038
系统。双精度 8字节 15-16位 +-5.0×10-324到+-1.7×10308
十进制 System.Decimal 16字节 28-29小数位 +-1.0×10-28到+-7.9×1028