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 运算符只能用于引用转换和装箱转换。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL - 聚簇索引和非聚簇索引,回表查询,索引覆盖,索引下推,最左匹配原则

聚簇索引和非聚簇索引 聚簇索引和非聚簇索引是 InnoDB 里面的叫法 一张表它一定有聚簇索引,一张表只有一个聚簇索引在物理上也是连续存储的 它产生的过程如下: 表中有无有主键索引,如果有,则使用主键索引作为聚簇索引;…

【Scala】Scala中的一些基本数据类型的特性 列表、元组、构造器、单例对象、伴生类、伴生对象、抽象类与特质

列表 使用List(“”,“”,“”)去声明 sliding 和 groued表示迭代器 val iter List("Hadoop", "Spark", "Scala") sliding 2// sliding 和 groued 是有区别的while (iter.hasNext){println(iter.next())}for (elem <- iter){println(elem)}…

极速学习SSM之SpringMVC笔记

文章目录 一、SpringMVC简介1、什么是MVC2、什么是SpringMVC3、SpringMVC的特点 二、HelloWorld1、开发环境2、创建maven工程a>添加web模块b>打包方式&#xff1a;warc>引入依赖 3、配置web.xmla>默认配置方式b>扩展配置方式 4、创建请求控制器5、创建springMVC…

Kafka 最佳实践:构建可靠、高性能的分布式消息系统

Apache Kafka 是一个强大的分布式消息系统&#xff0c;被广泛应用于实时数据流处理和事件驱动架构。为了充分发挥 Kafka 的优势&#xff0c;需要遵循一些最佳实践&#xff0c;确保系统在高负载下稳定运行&#xff0c;数据可靠传递。本文将深入探讨 Kafka 的一些最佳实践&#x…

四. 基于环视Camera的BEV感知算法-环视背景介绍

目录 前言0. 简述1. 环视背景介绍2. 环视思路3. 主流基于环视Camera的算法详解总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章——基于环视Camer…

基于Spring+Spring boot的SpringBoot在线电子商城管理系统

SSM毕设分享 基于SpringSpring boot的SpringBoot在线电子商城管理系统 1 项目简介 Hi&#xff0c;各位同学好&#xff0c;这里是郑师兄&#xff01; 今天向大家分享一个毕业设计项目作品【基于SpringSpring boot的SpringBoot在线电子商城管理系统】 师兄根据实现的难度和等级…

高云GW1NSR-4C开发板M3硬核应用

1.M3硬核IP下载&#xff1a;Embedded M3 Hard Core in GW1NS-4C - 科技 - 广东高云半导体科技股份有限公司 (gowinsemi.com.cn) 特别说明&#xff1a;IDE必须是1.9.9及以后版本&#xff0c;1.9.8会导致编译失败&#xff08;1.9.8下1.1.3版本IP核可用&#xff09; 以下根据官方…

vue3中关于echars的使用

今天介绍一个好用的插件echars&#xff0c;一个可视化插件Apache ECharts 一、使用步骤 1、安装 npm install echarts --save 2、导入 import * as echarts from echarts 3、正式使用 echars的使用非常的简单&#xff0c;直接点击官网有现成的代码的可用 代码示例 <t…

微服务——服务保护Sentinel

雪崩问题 在单体项目里面&#xff0c;如果某一个模块出问题会导致整个项目都有问题。 在微服务项目里面&#xff0c;单独一个服务出问题理论上是不会影响别的服务的。 但是如果有别的业务需要调用这一个模块的话还是会有问题。 问题产生原因和解决思路 最初那只是一个小小…

ChatGPT 应用开发(一)ChatGPT OpenAI API 免代理调用方式(通过 Cloudflare 的 AI Gateway)

前言 开发 ChatGPT 应用&#xff0c;我觉得最前置的点就是能使用 ChatGPT API 接口。首先我自己要能成功访问&#xff0c;这没问题&#xff0c;会魔法就可以本地调用。 那用户如何调用到我的应用 API 呢&#xff0c;我的理解是通过用户能访问到的中转服务器向 OpenAI 发起访问…

成都工业学院Web技术基础(WEB)实验四:CSS3布局应用

写在前面 1、基于2022级计算机大类实验指导书 2、代码仅提供参考&#xff0c;前端变化比较大&#xff0c;按照要求&#xff0c;只能做到像&#xff0c;不能做到一模一样 3、图片和文字仅为示例&#xff0c;需要自行替换 4、如果代码不满足你的要求&#xff0c;请寻求其他的…

Echarts 环形图配置 环形半径(radius) 修改文本位置(label) 南丁格尔图(roseType)

数据 const data [{ name: 华为, value: 404 },{ name: 小米, value: 800 }, { name: 红米, value: 540 }, { name: 苹果, value: 157 }]设置南丁格尔图 roseType: area设置标签位置 label: {show: true,position: center // center 中间展示 outside 外侧展示 inside 内侧…

C语言动态内存经典笔试题分析

C语言动态内存经典笔试题分析 文章目录 C语言动态内存经典笔试题分析1. 题目一2. 题目二3. 题目三4. 题目四 1. 题目一 void GetMemory(char *p){p (char *)malloc(100);} void Test(void){char *str NULL;GetMemory(str);strcpy(str, "hello world");printf(str)…

Qt设置类似于qq登录页面

头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QWindow> #include <QIcon> #include <QLabel> #include <QMovie> #include <QLineEdit> #include <QPushButton>QT_BEGIN_NAMESPACE namespace Ui { class…

数据分析基础之《numpy(2)—ndarray属性》

一、ndarray的属性 1、属性方法 属性名字属性解释ndarray.shape数组维度的元组&#xff08;形状&#xff09;ndarray.ndim数组维数ndarray.size数组中的元素数量ndarray.itemsize一个数组元素的长度&#xff08;字节&#xff09;ndarray.dtype数组元素的类型使用方法 数组名.…

大数据技术8:StarRocks极速全场景MPP数据库

前言&#xff1a;StarRocks原名DorisDB&#xff0c;是新一代极速全场景MPP数据库。StarRocks 是 Apache Doris 的 Fork 版本。StarRocks 连接的多种源。一是通过这个 CDC 或者说通过这个 ETL 的方式去灌到这个 StarRocks 里面&#xff1b;二是还可以去直接的和这些老的 kafka 或…

03-详解Nacos注册中心的配置步骤和功能

Nacos注册中心 服务注册到Nacos Nacos是SpringCloudAlibaba的组件也遵循SpringCloud中定义的服务注册和服务发现规范,因此使用Nacos与使用Eureka对于微服务来说并没有太大区别 主要差异就是依赖不同,服务地址不同 第一步: 在父工程cloud-demo模块的pom.xml文件中引入Spring…

nlkt中BigramAssocMeasures.pmi()方法的传参和使用

这个问题找遍全网没看到详细的介绍&#xff0c;最后用读代码数学公式的方法才理解怎么用。 BigramAssocMeasures.pmi 作用&#xff1a;计算x和y的互信息&#xff08;互信息是什么我就不科普啦&#xff09; 这里有个误区刚开始我以为是计算两个词之间的依赖程度&#xff0c;但…

flstudio21.3.2304高级版水果编曲音乐软件

flstudio高级版是一款适用于广泛领域的音频编辑软件。它支持多通道混音器和VST插件&#xff0c;包括数百种乐器和效果插件。它还为您提供了一个乐谱编辑器&#xff0c;需要对不同乐器的节奏进行必要的编辑。Flstudio具有许多内置电子合成声音&#xff0c;可提供更广泛的电子声音…

【Spring教程25】Spring框架实战:从零开始学习SpringMVC 之 SpringMVC入门案例总结与SpringMVC工作流程分析

目录 1.入门案例总结2. 入门案例工作流程分析2.1 启动服务器初始化过程2.2 单次请求过程 欢迎大家回到《Java教程之Spring30天快速入门》&#xff0c;本教程所有示例均基于Maven实现&#xff0c;如果您对Maven还很陌生&#xff0c;请移步本人的博文《如何在windows11下安装Mave…