C# 图解教程 第5版 —— 第17章 转换

文章目录

    • 17.1 什么是转换
    • 17.2 隐式转换
    • 17.3 显示转换和强制转换
    • 17.4 转换的类型
    • 17.5 数字的转换
      • 17.5.1 隐式数字转换
      • 17.5.2 溢出检测上下文
      • 17.5.3 显示数字转换
    • 17.6 引用转换
      • 17.6.1 隐式引用转换
      • 17.6.2 显式引用转换
      • 17.6.3 有效显式引用转换
    • 17.7 装箱转换
      • 17.7.1 装箱是创建副本
      • 17.7.2 装箱转换
    • 17.8 拆箱转换
    • 17.9 用户自定义转换
      • 17.9.1 用户自定义转换的约束
      • 17.9.2 用户自定义转换的示例
      • 17.9.3 评估用户自定义转换
      • 17.9.4 多步用户自定义转换的示例
    • 17.10 is 运算符
    • 17.11 as 运算符

17.1 什么是转换

  • 转换是接受一个类型的值并将它用作另一个类型的等价值的过程。
  • 转换后的值应和原值一样,但其类型为目标类型。

17.2 隐式转换

  1. 隐式转换不会丢失数据或精度,C# 会自动做这些转换。

  2. 从位数更少的源类型转换为位数更多的目标类型时,目标中多出来的位需要用 0 或 1 填充。

    • 对于无符号类型,目标类型多出来的最高位都用 0 来进行填充,称为零扩展
    image-20231206215536631
    图17.1 无符号转换中的零扩展
    • 对于有符号类型,额外的最高位用源表达式的符号位进行填充,称为符号扩展
image-20231206215407890
图17.2 有符号转换中的符号扩展
  1. C# 没有无符号扩展。

17.3 显示转换和强制转换

​ C# 不会提供会造成值丢失的自动转换。此时,需要使用强制转换表达式,这称为显示转换

  • 一对圆括号,里面是目标类型。
  • 圆括号后面是源表达式。
image-20231206215923366

​ 使用强制转换表达式,需要承担可能引起的丢失数据的后果。

image-20231206220011328
图17.3 强制转换 ushort 为 byte

17.4 转换的类型

  • 除了标准转换,还可以为自定义类型定义隐式转换和显示转换。
  • 有一个预定义的转换类型,称为装箱,可以将任何值类型转换为:
    • object 类型。
    • System.ValueType 类型。
  • 拆箱可以将一个装箱的值转换为原始类型。
image-20231206220245548
图17.4 转换的类型

17.5 数字的转换

​ 数字类型可以相互转换,但有些转换必须是显式的。

image-20231207000033891
图17.5 数字转换

17.5.1 隐式数字转换

  • 箭头方向表示存在从源类型到目标类型的隐式转换。
  • 若没有沿着箭头方向的路径,则该类型转换必须是显式的。
image-20231207000346245
图17.6 隐式数字转换

17.5.2 溢出检测上下文

​ 使用 checked 运算符或 checked 语句检测类型转换是否溢出。

  • 代码片段是否被检查称作溢出检测上下文
    • 如果指定一个表达式或一个代码为 checked,CLR 会在转换产生溢出时抛出 OverflowException 异常。
    • 如果代码不是 checked,转换会继续,不论是否产生溢出。
  • 默认的溢出检测上下文是不检查。

(1)checked 和 unchecked 运算符

image-20231207000723523
  • 在 unchecked 上下文中,会忽略溢出,结果值为 208。
  • 在 checked 上下文中,抛出了 OverflowException 异常。
image-20231207000756617 image-20231207000856758

(2)checked 语句和 unchecked 语句

​ checked 和 unchecked 控制的是一块代码中的所有转换,而不是单个表达式。

image-20231207001003795

17.5.3 显示数字转换

image-20231207001029226
图17.7 显式数字转换

(1)整数类型到整数类型

​ 如果转换会丢失数据:

  • checked 时,则抛出 OverflowException 异常。
  • unckecked 时,丢失的位不会发出警告。
image-20231207001157207
图17.8 整数到整数的显示转换

(2)float 或 double 转到整数类型

​ 如果转换会丢失数据:舍掉小数,截断为最接近的整数。

  • checked 时,则抛出 OverflowException 异常。
  • unckecked 时,C# 将不定义其值是什么。
image-20231207001531466
图17.9 转换 float 或 double 为整数类型

(3)decimal 到整数类型

​ 如果结果值不在目标类型的范围内,则 CLR 会抛出 OverflowException 异常。

image-20231207001117587
图17.10 转换 decimal 到整数

(4)double 到 float

​ double 被舍入到最接近的 float 值:

  • 值太小,则被设为 +0 或 -0。
  • 值太大,则被设为 +∞ 或 -∞。
image-20231207001853450
图17.11 转换 double 到 float

(5)float 或 double 到 decimal

  • 值太小,则被设为 0。
  • 值太大,则抛出 OverflowException 异常。
image-20231207001955651
图17.12 转换 float 或 double 到 decimal

(6)decimal 到 float 或 double

​ 总是会成功,但可能会损失精度。

image-20231207002055355
图17.13 转换 decimal 到 float 或 double

17.6 引用转换

​ 引用类型对象由内存中的两部分组成:引用和数据。

​ 引用转换接受源引用并返回指向堆中同一位置的引用,但是将引用“标记”为其他类型。

  • 对于 myVar1,引用对象看上去是类型 B 的对象(实际上就是)。
  • 对于 myVar2,同样的对象看上去像类型 A。
image-20231207130723138 image-20231207130742716
图17.14 引用转换返回与对象关联的不同类型

17.6.1 隐式引用转换

  • 所有引用类型可以被隐式转换为 object 类型。
  • 任何接口可以隐式转换为其继承的接口。
  • 类可以隐式转换为:
    • 继承链中的任何类。
    • 实现的任何接口。
image-20231207130958291
图17.15 类和接口的隐式转换
  • 委托可以隐式转换为 .NET BCL 类和接口。
  • ArrayS 数组(元素类型为 Ts)可以隐式转换为:
    • .NET BCL 类和接口。
    • 另一个满足如下条件的数组 ArrayT(元素类型为 Tt):
      1. 数组维度和 ArrayS 相同。
      2. Ts 和 Tt 都是引用类型。
      3. Ts 能隐式转换为 Tt。
image-20231207131257551
图17.16 委托和数组的隐式转换

17.6.2 显式引用转换

​ 显式引用转换是从普通类型到更精确类型的引用转换,包括:

  1. 从 object 到任何引用类型的转换。
  2. 从基类到派生类的转换。

​ 例如,将基类 A 的引用转换到派生类 B,并赋值给变量 myVar2.

  • 如果 myVar2 尝试访问 Field2,将会导致内存错误。
  • 这种不正确的强制转换会在运行时抛出 InvalidCastException 异常,但不会导致编译错误。
image-20231207131740441
图17.17 无效的转换抛出运行时异常

17.6.3 有效显式引用转换

​ 以下 3 种显示转换能够成功进行:

  1. 显示转换没有必要。

    即,已经发生了隐式转换。

image-20231207131957636
  1. 源引用为 null。

    尽管这样的类型转换通常不安全,但 C# 还是允许的。

image-20231207132043049
  1. 源引用指向的实际数据可以安全地进行隐式转换。
    • myVar2 看上去指向类型 A 的数据,但实际上指向的是类型 B。
image-20231207132224429
图17.18 强制转换到安全类型

17.7 装箱转换

​ 装箱是一种隐式转换,接受值类型,在堆上创建一个完整的引用类型对象并返回其引用。

​ 常见的装箱场景是将值类型当做参数传递给方法,但参数类型时对象的数据类型,装箱过程具体如下:

  • 在堆上创建 int 类型对象。
  • 将 i 的值复制给 int 对象。
  • 返回 int 对象的引用 oi。
image-20231207132702276
图17.19 装箱从值类型穿件了完整的引用类型

17.7.1 装箱是创建副本

​ 装箱返回的是值的引用类型副本。即,装箱之后,值有两份副本——原始值类型和引用类型副本,每一个都可以独立操作。

image-20231207132927683 image-20231207133001587 image-20231207133021488
图17.20 装箱创建了一份可以被独立操作的副本

17.7.2 装箱转换

​ 任何值类型 ValueTypeS 都可以被隐式转换为 object、System.ValueType 或 InferfaceT 类型(如果 ValueTypeS 实现了 InferfaceT)。

image-20231207133212039
图17.21 装箱是值类型到引用类型的隐式转换

17.8 拆箱转换

  • 拆箱是显式转换。
  • 系统在把值拆箱为 ValueTypeT 时执行了如下步骤:
    1. 检测到要拆箱的对象实际是 ValueTypeT 的装箱值。
    2. 将对象的值复制到变量。
  • 尝试将一个值拆箱为非原始类型时会抛出 InvalidCastException 异常。
image-20231207133524136 image-20231207133604848 image-20231207133618889 image-20231207133635312
图17.22 拆箱转换

17.9 用户自定义转换

​ 可以为类和结构定义隐式和显式转换。

  • 需要 public 和 static 修饰符。
  • implicit 和 explicit 分别表示隐式和显式转换。
image-20231207133847913

17.9.1 用户自定义转换的约束

  • 只可以为类和结构定义。
  • 不能重定义标准隐式或显式转换。
  • 对于源类型 S 和目标类型 T:
    • S 和 T 类型不能相同。
    • S 和 T 不能有继承关系。
    • S 和 T 不能同时为接口或 object。
    • 转换运算符必须定义在 S 或 T 类型的内部。
    • 不能同时声明隐式转换和显式转换。

17.9.2 用户自定义转换的示例

​ 隐式转换示例:

image-20231207134152236 image-20231207134244737 image-20231207134259771

​ 若使用显式转换,则需要:

image-20231207134344549

17.9.3 评估用户自定义转换

image-20231207134420162
图17.23 单步用户自定义转换

​ 完整转换中最多可以有 3 个步骤:

  1. 预备标准转换。
  2. 用户自定义转换。
  3. 后续标准转换。

​ 用户自定义转换只能有一次。

image-20231207134539358
图17.24 多步用户自定义转换

17.9.4 多步用户自定义转换的示例

image-20231207134652719 image-20231207134730222 image-20231207134746499
图17.25 从 Employee 转换到 float

17.10 is 运算符

​ is 运算符用于检查转换是否能成功。

image-20231207134912633

​ 以下 3 种转换适用于 is 运算符:

  1. 引用转换。
  2. 装箱转换。
  3. 拆箱转换。

​ is 运算符不能用于用户自定义转换。

17.11 as 运算符

​ as 运算符和强制转换运算符类似,但不会抛出异常,转换失败仅返回 null。

image-20231207135137893

​ as 运算符只能用于引用转换和装箱转换。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/245140.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小程序 -网络请求post/get

1.1网络请求的概念(post和get) 1.2步骤 1.3 应用函数 js里面写,用bindtap绑在控件上,就不讲了 实例代码: //发起get数据请求get_info(){wx.request({url:https://www.escook.cn/api/get,//请求的接口地址,必须基于https协议//请求的方式met…

SpringBoot的Starter自动化配置,自己编写配置maven依赖且使用及短信发送案例

目录 一、Starter机制 1. 是什么 2. 有什么用 3. 应用场景 二、短信发送案例 1. 创建 2. 配置 3. 编写 4. 形成依赖 6. 其他项目的使用 每篇一获 一、Starter机制 1. 是什么 SpringBoot中的starter是一种非常重要的机制(自动化配置),能够抛弃以前繁杂…

【五】Python 代理模式

文章目录 5.1 代理模式概述5.1.1 代理介绍5.1.2 代理模式的作用 5.2 代理模式的UML类图5.3 了解不同类型的代理5.3.1虚拟代理5.3.2 远程代理5.3.3 保护代理5.3.4 智能代理 5.4 现实世界中的代理模式5.5 代理模式的优点5.6 门面模式和代理模式之间的比较 5.1 代理模式概述 5.1.…

卷积神经网络(含案例代码)

概述 卷积神经网络(Convolutional Neural Network,CNN)是一类专门用于处理具有网格结构数据的神经网络。它主要被设计用来识别和提取图像中的特征,但在许多其他领域也取得了成功,例如自然语言处理中的文本分类任务。 C…

Paper Reading: (CCVC) 基于冲突的半监督语义分割跨视图一致性

目录 简介目标/动机工作重点方法CVC: 跨视图一致性CPL: 基于冲突的伪标记 实验设置comparison with SOTAAblation 总结 简介 题目:《Conflict-Based Cross-View Consistency for Semi-Supervised Semantic Segmentation》, CVPR’23, 基于冲突的半监督语…

HPM5300系列--第二篇 Visual Studio Code开发环境以及多种调试器调试模式

一、目的 在博文《HPM5300系列--第一篇 命令行开发调试环境搭建》、《HPM6750系列--第四篇 搭建Visual Studio Code开发调试环境》中我们介绍了命令行方式开发环境,也介绍了HPM6750evkmini开发板如何使用Visual Studio Code进行开发调试(其中调试方式使用…

AcWing 338. 计数问题

文章目录 题目描述问题分析代码 题目描述 AcWing 338.计数问题 给定两个整数 a a a 和 b b b, 求 a a a 和 b b b中所有数字中0~9的出现次数 数据范围&#xff1a; 0 < a, b < 100000000 输入格式&#xff1a; 输入包含多组测试数据。 每组测试数据占一行&#xff0c;包…

AI会干掉美图秀秀们吗?

网上流传着这样一个传说&#xff0c;亚洲有三大“邪术”&#xff0c;韩国整容术、日本化妆术&#xff0c;还有震惊世界的中国PS 术。虽然是网友的戏称&#xff0c;但也反映了PS美图技术在国内盛行一时。 而说起美图技术就不得不提到美图公司&#xff0c;但美图公司近些年的日子…

影视动画行业发展现状与方向:AI技术推动动画工业化体系新变革

工业化体系 是国产动画强国的必经之路 中国动画的百年历程不仅是创作者们展现艺术才华的历程&#xff0c;也是一代代中国动画人不懈追求动画工业体系建设的历程。 为什么现在的中国动画需要建立工业化体系呢&#xff1f; 举个例子&#xff0c;在建立工业化体系之前&#xff…

推荐一个小而全的第三方登录开源组件

大家好&#xff0c;我是 Java陈序员。 我们在企业开发中&#xff0c;常常需要实现登录功能&#xff0c;而有时候为了方便&#xff0c;就需要集成第三方平台的授权登录。如常见的微信登录、微博登录等&#xff0c;免去了用户注册步骤&#xff0c;提高了用户体验。 为了业务考虑…

网络基础(十):DHCP原理与配置

目录 1、DHCP的概念 2、使用DHCP的优势 3、DHCP的分配方式 4、可分配的地址信息 5、DHCP的工作原理&#xff08;租约过程&#xff09; 6、DHCP动态配置主机地址&#xff08;使用eNSP软件配置&#xff09; 1、DHCP的概念 DHCP(Dynamic HostConfiguration Protocol&#x…

SLAM学习——相机模型(针孔+鱼眼)

针孔相机模型 针孔相机模型是很常用&#xff0c;而且有效的模型&#xff0c;它描述了一束光线通过针孔之后&#xff0c;在针孔背面投影成像的关系&#xff0c;基于针孔的投影过程可以通过针孔和畸变两个模型来描述。 模型中有四个坐标系&#xff0c;分别为world&#xff0c;c…

vite(一)——基本了解和依赖预构建

文章目录 一、什么是构建工具&#xff1f;1.为什么使用构建工具&#xff1f;2.构建工具的作用&#xff1f;3.构建工具怎么用&#xff1f; 二、经典面试题&#xff1a;webpack和vite的区别1.编译方式不同2.基础概念不同3.开发效率不同4.扩展性不同5.应用场景不同6.总结&#xff…

孩子都能学会的FPGA:第三十一课——用FPGA实现SPI主机发送数据

&#xff08;原创声明&#xff1a;该文是作者的原创&#xff0c;面向对象是FPGA入门者&#xff0c;后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门&#xff0c;作者不光让大家知其然&#xff0c;还要让大家知其所以然&#xff01;每个工程作者都搭建了全自动化的仿…

【Python】conda镜像配置,.condarc文件详解,channel镜像

1. conda 环境 安装miniconda即可&#xff0c;Miniconda 安装包可以到 http://mirrors.aliyun.com/anaconda/miniconda/ 下载。 .condarc是conda 应用程序的配置文件&#xff0c;在用户家目录&#xff08;windows&#xff1a;C:\users\username\&#xff09;&#xff0c;用于…

SAP PP 配置学习(一)

物料主数据 一、定义物料类型属性 未检查的外部号分配&#xff1a;这是指如果用户自己输入的物料编码超出了定义的编码范围&#xff0c;是否会提示错误。 勾上代表不检查。 用户部门&#xff1a;这里勾选需要进行维护的视图&#xff0c;如果不选择&#xff0c;那么在新建和维…

苍穹外卖项目笔记(12)— 数据统计、Excel报表

前言 代码链接&#xff1a; Echo0701/take-out⁤ (github.com) 1 工作台 需求分析和设计 产品原型 工作台是系统运营的数据看板&#xff0c;并提供快捷操作入口&#xff0c;可以有效提高商家的工作效率 接口设计 ① 今日数据接口&#xff1a; ② 订单管理接口&#xff1…

智慧灯杆技术应用分析

智慧灯杆是指在传统灯杆的基础上&#xff0c;通过集成多种先进技术实现城市智能化管理的灯杆。智慧灯杆技术应用的分析如下&#xff1a; 照明功能&#xff1a;智慧灯杆可以实现智能调光、时段控制等功能&#xff0c;根据不同的需求自动调节照明亮度&#xff0c;提高照明效果&am…

论文阅读《Parameterized Cost Volume for Stereo Matching》

论文地址&#xff1a;https://openaccess.thecvf.com/content/ICCV2023/papers/Zeng_Parameterized_Cost_Volume_for_Stereo_Matching_ICCV_2023_paper.pdf 源码地址&#xff1a;https://github.com/jiaxiZeng/Parameterized-Cost-Volume-for-Stereo-Matching 概述 现有的立体匹…

SpringBoot整合Lucene实现全文检索【详细步骤】【附源码】

笑小枫的专属目录 1. 项目背景2. 什么是Lucene3. 引入依赖&#xff0c;配置索引3.1 引入Lucene依赖和分词器依赖3.2 表结构和数据准备3.3 创建索引3.4 修改索引3.5删除索引 4. 数据检索4.1 基础搜索4.2 一个关键词&#xff0c;在多个字段里面搜索4.3 搜索结果高亮显示4.4 分页检…