【C#基础】C# 数据类型总结
序号 | 系列文章 |
---|---|
0 | 【C#基础】初识编程语言C# |
1 | 【C#基础】C# 程序通用结构 |
2 | 【C#基础】C# 基础语法解析 |
文章目录
- 前言
- 数据类型
- 一. 值类型(Value types)
- 二. 引用类型(Reference types)
- 三. 指针类型(Pointer types)
- 结语
前言
😄大家好,我是writer桑,前面一章已经学习了C#的基础语法,那本章就开始学习C#程序的数据类型,希望看完大家能够有所收获,感谢支持!
数据类型
C# 是一种强类型语言。 每个变量和常量都有一个类型,每个求值的表达式也是如此。每个方法声明都为每个输入参数和返回值指定名称、类型和种类(值、引用或输出)。C# 分别以值类型和引用类型作为类型的两个主要类别。值类型的变量直接包含它们的数据。引用类型的变量存储对数据(称为“对象”)的引用。
一. 值类型(Value types)
值类型的变量包含类型的实例,不同于引用类型的变量包含对类型实例的引用。默认情况下,在分配中,通过将实参传递给方法并返回方法结果来复制变量值。 对于值类型,每个变量都具有其自己的数据副本,对一个变量执行的操作不会影响另一个变量(ref 和 out 参数变量除外)。
代码理解:
using System;public struct MutablePoint
{public int X, Y;public MutablePoint(int x, int y) => (X, Y) = (x, y);public override string ToString() => $"({X}, {Y})";
}public class Program
{public static void Main(string[] args){var p1 = new MutablePoint(1, 2);var p2 = p1;Console.WriteLine($"{nameof(p1)} after {nameof(p2)} is modified:{p1} ");Console.WriteLine($"{nameof(p2)}: {p2}");MutateAndDisplay(p2);Console.WriteLine($"{nameof(p2)} after passing to a method: {p2}");}private static void MutateAndDisplay(MutablePoint p){p.X = 100;Console.WriteLine($"Point mutated in a method: {p}");}
}/*
* 预期的输出:
* p1 after p2 is modified:(1, 2)
* p2: (1, 2)
* Point mutated in a method: (100, 2)
* p2 after passing to a method: (1, 2)
*/
- 从运行结果可知 MutateAndDisplay 方法对传入的参数 p 的修改并不会影响 Main 方法中的 p2 参数。
- MutateAndDisplay 方法对值类型变量 p 的操作只影响当前代码所处的栈内存的变量,而 Main 方法的 p2 变量和 p 变量又是两个不同的变量。
- 结论:对值类型变量的操作只影响存储在变量中的值类型实例。
下表列出了 C# 11 中值类型的简单类型:
类型/关键字 | 描述 | 范围 | 默认值 | .NET类型 |
---|---|---|---|---|
bool | 布尔值 | True 或 False | False | System.Boolean |
char | 16位 Unicode 字符 | U+0000 到 U+FFFF | ‘\0’ | System.Char |
float | 32 位单精度浮点型 | ±1.5 x 10-45 至 ±3.4 x 1038 | 0.0F | System.Single |
double | 64 位双精度浮点型 | ±5.0 × 10 -324 至±1.7 × 10308 | 0.0D | System.Double |
decimal | 128 位精确的十进制值,28-29 有效位数 | ±1.0 x 10-28 至7.9228 x 10^28 | 0.0M | System.Decimal |
sbyte | 8 位有符号整数类型 | -128 到 127 | 0 | System.SByte |
byte | 无符号的 8 位整数 | 0 到 255 | 0 | System.Byte |
short | 有符号 16 位整数 | -32,768 到 32,767 | 0 | System.Int16 |
ushort | 无符号 16 位整数 | 0 到 65,535 | 0 | System.UInt16 |
int | 带符号的 32 位整数 | -2,147,483,648 到 2,147,483,647 | 0 | System.Int32 |
uint | 带符号的 32 位整数 | 0 到 4,294,967,295 | 0 | System.UInt32 |
long | 64 位带符号整数 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 0L | System.Int64 |
ulong | 无符号 64 位整数 | 0 到 18,446,744,073,709,551,615 | 0 | System.UInt64 |
nint | 带符号的 32 位或 64位整数 | 取决于(在运行时计算的)平台 | 0 | System.IntPtr |
nuint | 带符号的 32 位或 64 位整数 | 取决于(在运行时计算的)平台 | 0 | System.UIntPtr |
除了上述值类型的简单类型之外,C# 程序还包括以下用关键字声明的值类型种类:
1,枚举类型(Enumeration)
枚举类型是由基础整型数值类型的一组命名常量定义的值类型。 C# 程序中使用 enum 关键字定义枚举类型并指定枚举成员的名称,示例代码如下:
enum Season
{Spring,Summer,Autumn,Winter
}
2,结构类型(Structure)
结构类型是是一种可封装数据和相关功能的值类型,C# 程序中使用 struct 关键字定义结构类型,示例代码如下:
public struct MutablePoint
{public int X, Y;public MutablePoint(int x, int y) => (X, Y) = (x, y);public override string ToString() => $"({X}, {Y})";
}
3,元组类型(Tuple)
元组功能提供了简洁的语法来将多个数据元素分组成一个轻型数据结构。 下面的示例演示了如何声明元组变量、对它进行初始化并访问其数据成员:
(double, int) t1 = (4.5, 3);
Console.WriteLine($"Tuple with elements {t1.Item1} and {t1.Item2}.");
// Output:
// Tuple with elements 4.5 and 3.(double Sum, int Count) t2 = (4.5, 3);
Console.WriteLine($"Sum of {t2.Count} elements is {t2.Sum}.");
// Output:
// Sum of 3 elements is 4.5.
4,可为空的值类型(Null)
可为 null 值类型 T?(T 表示泛型)表示其基础值类型T 的所有值及额外的 null 值,示例代码如下:
// 值类型可隐式转换为相应的可为空的值类型
double? pi = 3.14;
char? letter = 'a';int m2 = 10;
int? m = m2;bool? flag = null;// 可空值类型的数组:
int?[] arr = new int?[10];
一些针对值类型的常用操作:
- 若要在运行时获取本机大小的整数大小,可以使用 sizeof()。 但是,必须在不安全的上下文中编译代码。示例代码:
Console.WriteLine($"size of nint = {sizeof(nint)}");
Console.WriteLine($"size of nuint = {sizeof(nuint)}");// 在64位进程中运行时输出
//size of nint = 8
//size of nuint = 8// 在32位进程中运行时输出
//size of nint = 4
//size of nuint = 4
- 若要在运行时获取本机大小的整数的最小值和最大值或者取值范围,请将 MinValue 和 MaxValue用作值类型关键字的静态属性,示例代码:
Console.WriteLine($"nint.MinValue = {nint.MinValue}");
Console.WriteLine($"nint.MaxValue = {nint.MaxValue}");//nint.MinValue = -9223372036854775808
//nint.MaxValue = 9223372036854775807
- 如果想在运行时实现值类型数据之间的相互转换,请使用隐式转换或者显式转换,示例代码:
// 隐式数据转换举例:int 转换为 long
int a = 11;
long b = a; // 显示数据转换:long 转换为 int
int a1 = 123;
long b1 = a;
int c = (int)b1;
- 如果想在运行时输出值类型的默认值,可以使用 default 运算符生成默认类型值,例如:
Console.WriteLine(default(bool)); // False
- 如果想在运行时输出值类型数据的 .NET 类型,可以使用 GetType 方法,例如:
bool b = false;
Console.WriteLine(b.GetType()); // System.Boolean
二. 引用类型(Reference types)
引用类型的变量存储对其数据(对象)的引用,不同于值类型的变量直接包含其数据。 对于引用类型,多个变量可同时引用同一对象,多个变量之间互相传递的也是对这个对象的引用;因此,对一个变量执行的操作会影响另一个变量所引用的对象(这点区别于值类型)。
代码理解:
using System;// 类为引用类型
public class MutablePoint
{public int X, Y;public MutablePoint(int x, int y) => (X, Y) = (x, y);public override string ToString() => $"({X}, {Y})";
}public class Program
{public static void Main(string[] args){var p1 = new MutablePoint(1, 2);var p2 = p1;Console.WriteLine($"{nameof(p1)} after {nameof(p2)} is modified:{p1} ");Console.WriteLine($"{nameof(p2)}: {p2}");MutateAndDisplay(p2); // 显示和改变 Console.WriteLine($"{nameof(p2)} after passing to a method: {p2}");}private static void MutateAndDisplay(MutablePoint p){p.X = 100;Console.WriteLine($"Point mutated in a method: {p}");}
}/*
* 预期的输出:
* p1 after p2 is modified:(1, 2)
* p2: (1, 2)
* Point mutated in a method: (100, 2)
* p2 after passing to a method: (100, 2)
*/
- 从输出结果可知 MutateAndDisplay 方法对参数 p 修改的同时也修改了 Main 方法中的 p2 参数。
- 因为 p2 变量和 p 变量都是引用同一个对象 MutablePoint 类,也就是指向了同一块内存地址,所以 p2 变量对这内存进行修改的同时也修改了 p 变量的内存,两者同时发生变化。
- 结论:当两个变量引用同一个对象时,一个变量执行的操作会影响另一个变量的运行结果。
以下表格列举出了 C# 内置引用类型:
类型/关键字 | 描述 | .NET 类型 |
---|---|---|
object | 对象类型 | System.Object |
string | 字符串类型 | System.String |
dynamic | 动态类型 | System.Object |
除了上述内置的引用类型之外,C# 程序还包括以下用关键字声明的引用类型:
1,记录类型(Record)
从 C# 9 开始,可以使用 record 关键字定义一个 record 类型,用来提供用于封装数据的内置功能,record 类型用来构建不可变类型和和线程安全对象,简单的示例:
// 声明 record class 引用类型:
public record Person
{public string FirstName { get; init; } = default!;public string LastName { get; init; } = default!;
};// 声明 record struct 值类型:
public record struct Point
{public double X { get; init; }public double Y { get; init; }
}
2,类类型(Class)
类是将同类对象的共同属性和行为抽象出来形成的一个相对复杂的数据类型,在 C# 程序中使用 class 关键字声明类,示例如下:
class TestClass
{//方法,属性,字段,事件,委托//和嵌套类到这里。
}
3,接口类型(Interface)
接口定义"协定",继承接口的类或结构体都必须实现接口中所定义的成员,在 C# 编程中使用 interface 关键字定义接口,示例如下:
// 定义接口 ISampleInterface
interface ISampleInterface
{void SampleMethod();
}// 类 Program 继承接口并实现
public class Program : ISampleInterface
{public void SampleMethod(){throw new NotImplementedException();}
}
4,可为空的引用类型(Null)
引用类型 T? 的变量也可以用 null 进行初始化,注意在取消引用之前必须检查变量是否为空, 示例如下:
string notNull = "Hello";
string? nullable = default;
notNull = nullable!; // 给定为空值
一些针对引用类型的常用操作:
- 常见的装拆箱操作,当一个值类型转换为对象类型时,则被称为装箱;相对的,当一个对象类型转换为值类型时,则被称为拆箱,示例如下:
//将整型变量i进行了装箱并分配给对象o。
int i = 123;
object o = i;// 将对象o拆箱并分配给对象i;
i = (int)o;Console.WriteLine(i); // 123
- string 字符串类型常见的相等运算、连接操作、输出指定位置的字符操作,示例如下:
string s1 = "hello, world";
string s2 = "hello, C#";// 定义相等运算符 == 和 != 比较 string 对象之间是否相等:
Console.WriteLine(s1 == s2); // False // 定义 + 连接运算符连接两个字符串:
Console.WriteLine(s1 + s2); // hello, worldhello, C# // 定义 [] 运算符可访问字符串指定位置的字符:
Console.WriteLine(s1[0]); // h
- 当希望变量不在编译期间进行类型检查时, 使用 dynamic 类型的变量表示,dynamic 类型变量在运行期间才进行解析,示例如下:
dynamic d = 20; // 运行时进行类型检查
三. 指针类型(Pointer types)
C# 程序中在不安全的上下文中,类型除了是值类型或引用类型外,还可以是指针类型 , 通过指针类型可以直接操作对象的内存,指针类型声明采用下列形式之一:
//type* identifier;
void* identifier; // 允许但不建议 // 又例如:
char* cptr;
int* iptr;
- 指针类型不能从对象继承,并且指针类型之间不存在类型转换
- 指针类型不支持类型装箱和拆箱的操作
- 指针不能指向引用或包含引用的结构,因为无法对对象引用进行垃圾回收
- MyType* 类型的指针变量的值为 MyType 类型的变量的地址
(ps:指针类型不在本章进行详细的讨论。)
结语
✔️ 以上就是 C# 数据类型的介绍,希望能够对大家有所帮助。望大家多多支持,你们的支持就是笔者创作最大的动力!
相关文章:
【C#基础】C# 数据类型总结
序号系列文章0【C#基础】初识编程语言C#1【C#基础】C# 程序通用结构2【C#基础】C# 基础语法解析文章目录前言数据类型一. 值类型(Value types)二. 引用类型(Reference types)三. 指针类型(Pointer types)结…...

再创荣誉 | Softing工业荣获CAIMRS 2023 数字化创新奖
在刚刚结束的中国工控-第二十一届“自动化及数字化”年度评选(CAIMRS 2023)中,Softing凭借edgeAggregator产品荣获“数字化创新奖”! 经层层筛选,Softing edgeAggregator边缘聚合服务器从中脱颖而出,摘得C…...

Multi Paxos
basic paxos 是用于确定且只能确定一个值,“只确定一个值有什么用?这可解决不了我面临的问题,例如每个用户都要多次保存数据.” 你心中可能有这样的疑问。 原simple paxos论文里有提到一连串个instance of paxos [4] 但没有提出 multi paxos的概念&…...

Android - dimen适配
一、分辨率对应DPIDPI名称范围值分辨率名称屏幕分辨率density密度(1dp显示多少px)ldpi120QVGA240*3200.75(120dpi/1600.75px)mdpi160(基线)HVGA320*4801(160dpi/1601px)hdpi240WVGA4…...

深度学习网络模型——RepVGG网络详解
深度学习网络模型——RepVGG网络详解0 前言1 RepVGG Block详解2 结构重参数化2.1 融合Conv2d和BN2.2 Conv2dBN融合实验(Pytorch)2.3 将1x1卷积转换成3x3卷积2.4 将BN转换成3x3卷积2.5 多分支融合2.6 结构重参数化实验(Pytorch)3 模型配置论文名称: RepVGG: Making V…...

仓库拣货标签应用案例
使用场景:富士康成都仓库 解决问题:仓库亮灯拣选, 提高作业效率和物料明晰展示仓库亮灯拣选使用场景:京东仓库 解决问题:播种墙分拣,合单拣货完成后按订单播种播种墙分拣使用场景:和尔泰智能料…...

介绍一款HCIA、HCIP、HCIE的刷题软件
华为认证考试分为三个等级,分别为工程师HCIA、高级工程师HCIP、专家HCIE,等级越高,考试难度越大。 本篇带大家详细了解华为数通题库刷题工具的详细操作步骤。 操作须知:本款刷题工具为一款刷题小程序,无需安装即可在线…...

线程池整理汇总
它山之石,可以攻玉。借鉴整理线程池相关文章,以及自身实践。 文章目录1. 线程池概述2. 线程池UML架构3. Executors创建线程的4种方法3.1 newSingleThreadExecutor3.2 newFixedThreadPool3.3 newCachedThreadPool3.4 newScheduledThreadPool小结4. 线程池…...
华为OD机试真题Python实现【最短木板长度】真题+解题思路+代码(20222023)
🔥系列专栏 华为OD机试(Python)真题目录汇总华为OD机试(JAVA)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出示例一输入输出说明示例二输入输出说明...

VMware安装CentOS7
个人简介:云计算网络运维专业人员,了解运维知识,掌握TCP/IP协议,每天分享网络运维知识与技能。个人爱好: 编程,打篮球,计算机知识个人名言:海不辞水,故能成其大;山不辞石…...
力扣24.两两交换链表中的节点
文章目录力扣24.两两交换链表中的节点题目描述方法1:非递归方法2:递归力扣24.两两交换链表中的节点 题目描述 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&…...
AtCoder Regular Contest 137 题解(A~C)
A-Coprime Pair 思路 我们知道两个质数之间并不会相隔太远,于是我们直接用暴力就可以通过这题。 先从大到小枚举答案,并且枚举所有可能的起点,当枚举到的两个值满足条件输出并结束程序即可。 代码 #include <bits/stdc.h> using n…...
【C语言】预处理指令
C语言预处理指令一、什么是预处理指令二、预处理指令特点三、文件包含四、C标准库<stdio.h>一、什么是预处理指令 C语言的源文件(.c文件)需要经过编译生成可执行程序,编译操作会将源文件转换成目标文件,对于 VC、VS&#x…...

Java基础之多线程JUC全面学习笔记
目录初识多线程多线程的实现方式常见的成员方法线程安全的问题死锁生产者和消费者线程池自定义线程池初识多线程 什么是多线程? 线程 线程是操作系统能够进行运算调度的最小单位。线程被包含在进程之中,是进程中的实际运作单位。 简单理解:应用软件中互相独立&…...
13.CSS文本样式
文本样式 h1 {color: blue; }● 回顾上一节的内容,我们让h1标题的文字变成了蓝色,注意如果html中有多个h1标签,那我们这种写法所有的h1标签都会变成蓝色,除了颜色,本节我们将学习更多的CSS属性 文字大小font-size h…...
西恩科技更新招股书:IPO前大手笔分红“套现”, 赵志安为实控人
2月14日,上海西恩科技股份有限公司(下称“西恩科技”)更新了招股书(申报稿)。据贝多财经了解,西恩科技于2022年8月12日递交上市申请材料,准备在创业板上市,此次是西恩科技第二次更新…...

【CentOS】有关时间的设置
目录环境信息date语法信息查看时间设置时间设置日期tzselecttimedatectl语法显示当前及所有时区修改时区hwclock语法读取硬件时钟使用硬件时钟设置系统时间使用系统时间设置硬件时钟如何理解硬件时钟和系统时钟环境信息 CentOS 7 date 语法信息 date --help用法:…...

OpenCV制作Mask图像掩码
一、掩膜(mask) 在有些图像处理的函数中有的参数里面会有mask参数,即此函数支持掩膜操作,首先何为掩膜以及有什么用,如下: 数字图像处理中的掩膜的概念是借鉴于PCB制版的过程,在半导体制造中&am…...

C++STL剖析(九)—— unordered_map和unordered_multimap的概念和使用
文章目录1. unordered_map的介绍和使用🍑 unordered_map的构造🍑 unordered_map的使用🍅 insert🍅 operator[ ]🍅 find🍅 erase🍅 size🍅 empty🍅 clear🍅 sw…...

Android无菜单键,如何触发onCreateOptionsMenu(Menu menu)
文章目录小结问题及解决无法触发onCreateOptionsMenu(Menu menu)修改配置文件解决使用一个按钮来触发其它办法参考小结 现在的Android有三个键: 任务键,Home键,返回键,也就是没有菜单键了,那么如何如何触发onCreateOp…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...