C#中的转换

一、什么是转换

  1. 将一个类型转换为另外一个类型;
  2. 可以是两个值类型之间的转换;
  3. 可以是两个引用类型之间的转换;
  4. 可以是值类型和引用类型之间的转换(拆箱与装箱);
  5. 可以用户自定义转换。
  6. 转换的时候有隐式转换/自动转换和显示转换/强制转换。

 

二、值类型之间的转换

1.隐式转换/自动转换

  1. 范围小的值类型 转 范围大的值类型,不丢失数据精度。
  2. 隐式转换最高位用符号位(二进制补码)进行扩展,保证数值的正负是正确的。
  3. 正数符号位是0,使用0进行扩展的叫做零扩展。
  4. 负数符号位是1,使用1进行扩展的叫做符号扩展。

 值类型之间的隐式转换关系如下图:

2.显示转换/强制转换 

  1. 范围大的值类型 转 范围小的值类型,无法保证精度不丢失。
  2. 需要使用强转表达式完成转换。

 显示转换/强制转换理解示例:

  • ushort范围:0~65535
  • byte范围:0~255
  • 只要希望转换的ushort值小于256,就不会损失数据,否则最高位的数据将丢失(溢出)。

 3.值类型之间的转换关系

现在我们应该已经知道,占据较少位的值类型可以隐式转换为占据较多位的值类型。

 三、溢出检测上下文

在类型转换时,进行检测结果是否溢出的代码片段称为溢出检测上下文。

  1. 如果我们指定一个表达式或一段代码为checked,CLR会在转换产生溢出时抛出一个异常。
  2. 默认溢出检测上下文是不检查,如果不检查,转换将继续而不管是否产生溢出。

1.checked和unchecked运算符

 

 2.checked语句和unchecked语句

checked语句和unchecked语句可以嵌套在任意层次。

四、引用类型之间的转换 

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

 1.隐式转换/自动转换

  1. 类可以隐式转换到它继承链中任何类以及它实现的任何接口。
  2. 所有引用类型可以被隐式转换到object类型。
  3. 任何类型可以隐式转换到它继承的接口。

 委托可以隐式转换为.NET BCL类和接口。

ArrayS数组,其中的元素都是Ts类型,可以隐式转换:

        a.  .NET BCL类和接口

        b.  另一个数组ArrayT,其中元素都是Tt类型(当满足下面所有条件可转换)

                i. 两个数组有一样的维度

                ii. 元素Ts和元素Tt都是引用类型,而不是值类型

                iii. 在元素Ts和Tt之间存在隐式转换

 2.显示转换/强制转换

  1. 从object到任何引用类型的转换
  2. 从基类到它继承的类的转换
  • 无效强制转换

如果将基类强制转换成派生类时,派生类并没有创建对象,就将一个基类对象直接强转为派生类对象,会报InvalidCastException异常(无效强制转换异常)。

 

  • 有效强制转换

第一种情况:派生类转基类,本身是隐式转换,可以但没必要的强制转换。

第二种情况:源引用为null

第三种情况:派生类先转基类,再基类转派生类。(先向上转型,再向下转型) 

五、值类型和引用类型之间的转换

1.装箱

  1. 含义: 值类型隐式转换成引用类型
  2. 装箱产生一个原始值类型和引用类型副本,每一个都可以独立进行操作。

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

2.拆箱

  1. 含义:把装箱后的对象转换成值类型的过程。
  2. 拆箱是显示转换。
  3. 尝试将一个值拆箱为非原始类型,会抛出一个InvalidCastException异常。

六、用户自定义转换

除了标准转换,我们还可以为类和结构定义隐式或显示转换。

  1. 需要public和static修饰
  2. 除了implicit和explicit关键字之外,隐式和显示转换的声明语法是一样的。
  3. 语法格式如下:

 用户自定义转换的约束:

  1. 只可以为类和结构定义用户自定义转换。
  2. 不能重定义标准隐式转换或强制转换。
  3. 对于相同的源类型S和目标类型T,不能声明隐式转换或强制转换。
  4. 对于源类型S和目标类型T,以下命题为真:

                i.S和T必须是不同类型

                ii.S和T不能通过继承关联

                iii.S和T都不能是接口类型或object类型

                iiii.转换运算符必须是S或T的成员

1.单步用户自定义转换

隐式转换代码示例:

    internal class Person
    {
        public string Name;
        public int Age;

        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }

        //将Person隐式转换为int
        public static implicit operator int(Person person)
        {
            return person.Age;
        }

        //将int类型转换成Person类型
        public static implicit operator Person(int i)
        {
            return new Person("NONE", i);
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            Person bill = new Person("Bill", 25);

            int age = bill;//将bill隐式转换为int类型
            Console.WriteLine("Person Info:{0},{1}",bill.Name,age);

            Person person = 17;//将int类型隐式转换为Person类型
            Console.WriteLine("Person Info:{0},{1}", person.Name, person.Age);
        }

    }

显示转换代码示例:


    internal class Person
    {
        public string Name;
        public int Age;

        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }

        //将Person显式转换为int
        public static explicit operator int(Person person)
        {
            return person.Age;
        }

        //将int类型转换成Person类型
        public static explicit operator Person(int i)
        {
            return new Person("NONE", i);
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            Person bill = new Person("Bill", 25);

            int age = (int)bill;//将bill显式转换为int类型
            Console.WriteLine("Person Info:{0},{1}",bill.Name,age);

            Person person =(Person) 17;//将int类型显式转换为Person类型
            Console.WriteLine("Person Info:{0},{1}", person.Name, person.Age);
        }

    }

2.多步用户自定义转换

在用户自定义转换时,可能存在多种转换组合。

 代码示例:

    class Employee : Person { }

    class Person 
    {
        public string Name;
        public int Age;

        //将Person对象转换为int
        public static implicit operator int(Person person) 
        {
            return person.Age;
        }

    }
    

    internal class Program
    {
        static void Main(string[] args)
        {
            Employee bill = new Employee();
            bill.Name = "Wakaka";
            bill.Age = 17;

            //1.普通转换:       Employee -->  Person
            //2.用户自定义转换:  Person   -->  int
            //3.普通转换:       int      -->  float
            float fVar = bill;

            Console.WriteLine("Person Info: {0},{1}",bill.Name,fVar);
          
        }

    }

代码图解:

七、is和as运算符

1. is运算符

 我们可以使用is运算符来检查转换是否会成功,避免盲目转换。

  1. 语法:Expr is TargetType;
  2. is运算符只能用于引用转换,以及拆箱、装箱转换,不能用于用户自定义转换。
    class Employee : Person { }

    class Person 
    {
        public string Name = "光头强";
        public int Age = 25;

    }

    internal class Program
    {
        static void Main(string[] args)
        {
            Employee employee = new Employee();

            Person person;

            if (employee is Person) //检测employee是否能转换为Person类型
            {
                person = employee;
                Console.WriteLine("Person Info: {0},{1}", person.Name,person.Age);
            }
        }
    }

2. as运算符

as运算符和强制运算符类似,但如果转换失败,返回null,而不是抛异常。

  1. 语法:Expr as TargetType;
  2. TargetType是目标类型,必须是引用类型
  3. as运算符只能用于引用转换和装箱转换,不能用于用户自定义转换或到值类型的转换。
    class Employee : Person { }

    class Person 
    {
        public string Name = "光头强";
        public int Age = 25;

    }

    internal class Program
    {
        static void Main(string[] args)
        {
            Employee employee = new Employee();

            Person person;

            person = employee as Person;
            if (person != null) 
            {
                person = employee;
                Console.WriteLine("Person Info: {0},{1}", person.Name,person.Age);
            }
        }
    }

(注:本章学习总结自《C#图解教程》)

 

 

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

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

相关文章

lombok快速入门

Lombok是一个实用的Java类库&#xff0c;可以通过简单的注解来简化和消除一些必须有但显得很臃肿的Java代码。 通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法&#xff0c;并可以自动化生成日志变量&#xff0c;简化java开发、提高效率。 <…

好用到爆的windows文件检索工具--Everything

如果你的电脑是windows系统&#xff0c;那么这款软件强烈推荐大家安装>Everything&#xff0c;他可以帮助你快速的检索的磁盘里的文件&#xff0c;话不多说&#xff0c;开始安装 1.下载 访问https://www.voidtools.com/zh-cn/会跳转官方下载地址 双击安装包运行 效果如下…

Tensor张量基础与常用方法【Pytorch】

Tensor中文译名为张量&#xff0c;标量是零维张量&#xff0c;向量是一维张量&#xff0c;矩阵是二维张量&#xff0c;矩阵的堆叠是三维张量…… 张量的维数可以无穷大&#xff0c;不过由于现实世界是三维的&#xff0c;因此更高维度的图形我们无法想象&#xff0c;但是这并不…

即时通讯-6-已读回执的方案设计

背景-为什么展示已读未读 部分即时通讯软件会选择展示给用户已读未读&#xff0c; 主要是快速感知对方的阅读状态&#xff0c; 感觉到自己受重视&#xff0c; 方便做下一步操作。 如果要带点高度的讲&#xff0c;满足软件所代表的关键用户的诉求 什么场景下要展示已读回执 t…

462. 最小操作次数使数组元素相等 II——【Leetcode每日一题】

462. 最小操作次数使数组元素相等 II 给你一个长度为 n 的整数数组 nums &#xff0c;返回使所有数组元素相等需要的最小操作数。 在一次操作中&#xff0c;你可以使数组中的一个元素加 1 或者减 1 。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;2 …

微信小程序获取手机号47001 data format error hint的完美解答(restTemplate发送post请求)

发现问题 这几天正在搞微信小程序获取手机号功能开发&#xff0c;发现发送post请求接口时候&#xff0c;接口返回如下错误&#xff1a; {"errcode": 47001,"errmsg": "data format error hint: [******] rid: ******" } post请求的url为&…

动态代理原理

一、案例分析 1、引出问题 回到Spring之初控制事务繁琐的问题。 回到Spring之初控制事务繁琐的问题. 考虑一个应用场景∶需要对系统中的某些业务方法做事务管理&#xff0c;拿简单的save和update操作举例。没有加上事务控制的代码如下。 加上事务代码&#xff0c;如下&#x…

大数据平台开发——使用Java和Python调用Shell脚本

大数据平台开发——使用Java和Python调用Shell脚本 背景 在大数据平台开发中&#xff0c;经常会遇到需要调用Shell脚本的场景&#xff0c;倒不是说只能用Shell&#xff0c;毕竟大数据开发到头来一定是个语言无关的事情&#xff1a; 从Hive源码解读大数据开发为什么可以脱离S…

Java进阶

注解 什么是注解 Java注解&#xff08;Annotation&#xff09;又称Java标注&#xff0c;是JDK5.0引入的一种注释机制。 Java语言中类、方法、变量、参数和包等都可以被标注。Java标注可以通过反射获取标注内容。在编译器生成类文件时&#xff0c;标注可以被嵌入到字节码中。Ja…

【Python实操】一行代码就可以自动画出这种艺术画?(详细教程)

文章目录前言一.准备阶段二、开始使用 Discoart1.引入库2.显示/保存/加载配置总结前言 DiscoArt 是一个很牛逼的开源模块&#xff0c;它能根据你给定的关键词自动绘画。 绘制过程是完全可见的&#xff0c;你可以在 jupyter 页面上看见这个绘制的过程&#xff1a; 一.准备阶段…

零拷贝内存 固定内存

一、总览 虚拟内存是一种计算机内存管理的技术&#xff0c;它让程序认为程序自身有一段完整的连续可用的内存&#xff08;一个地址空间&#xff09;。当程序运行时所占的内存空间大于物理空间容量&#xff0c;操作系统可以将暂时不用的数据放入到磁盘&#xff0c;用的时候再拿出…

Linux--高级IO--select--0326

目录 IO为什么低效&#xff1f; 1.快速理解五种IO模式 2.五种IO模型 3.非阻塞IO fcntl() 4.IO多路转接 select select fd_set类型 struct timeval*类型 5.Select的代码测试 5.1 问题一&#xff1a;一开始&#xff0c;我们只有一个listen套接字 5.2 问题二&#xff1…

《项目管理知识体系指南(PMBOK)》第7版之8大绩效域

项目绩效域被定义为一组对有效交付项目成果至关重要的相关活动。 《项目管理知识体系指南&#xff08;PMBOK&#xff09;》第7版将项目管理划分为干系人、团队、开发方法和生命周期、规划、项目工作、交付、测量、不确定性共8大绩效域。 一、干系人绩效域 解决与干系人相关的…

【对YOLOv8(ultralytics)打印测试结果的调整】(1)使得map值打印显示从0.551变为55.08 (2)打印出FPS

目录1. 最终打印效果2. 做两处更改2.1 修改map显示&#xff0c;在ultralytics-main/ultralytics/yolo/v8/detect/val.py中操作2.2 打印FPS&#xff0c;在ultralytics-main/ultralytics/yolo/engine/validator.py中操作❗❗❗ 兄弟姐妹们&#xff0c;如果看习惯了运行train.py时…

PMP应该如何备考?

PMP现在是新考纲&#xff0c;PMP新版大纲加入了 ACP 敏捷管理的内容&#xff0c;而且还不少&#xff0c;敏捷混合题型占到了 50%&#xff0c;前不久官方也发了通知 8月启用第七版《PMBOK》&#xff0c;大家都觉得考试难度提升了&#xff0c;我从新考纲考完下来&#xff0c;最开…

Moonbeam隆重推出您的个人开发小助手 — — Kapa.ai

Moonbeam为开发者提供内容详细的开发者文档和全天候的Discord支持。但假如&#xff1a;有人可以24/7查看Discord并在15秒之内就回复您的问题 — — 新推出的Kapa.ai机器人使这个假如成为现实。Kapa.ai是一款由ChatGPT支持的AI机器人&#xff0c;可以回答关于在Moonbeam上构建的…

【redis】单线程redis为什么这么快

本文以收录专栏 redis核心技术 前言 本专栏为了帮助大家更好的了解学习redis&#xff0c;同时也是自己记录学习redis的内容&#xff0c;包含了大部分的redis核心技术&#xff0c;分布式锁&#xff0c;主从复制等 目录 专题2-单线程redis为什么这么快 2.1redis只有单线程吗&a…

剑指offer-替换空格

替换空格一、解题思想二、代码的实现三、总结一、解题思想 题目&#xff1a;请实现一个函数 &#xff0c;把字符串中的每个空格替换成”%20“。例如&#xff1a;输入”We are happy.“&#xff0c;则输出”We%20are%20happy.“。 看到这个题目&#xff0c;我第一想到的是&#…

博客1:YOLOv5车牌识别实战教程:引言与准备工作

摘要:本篇博客介绍了本教程的目标、适用人群、YOLOv5简介和车牌识别的意义和应用场景。为后续章节打下基础,帮助读者了解YOLOv5和车牌识别的相关背景知识。 正文: 车牌识别视频 引言 欢迎来到YOLOv5车牌识别实战教程!在这个教程中,我们将一步步教你如何使用YOLOv5进行车…

【Git Bash】项目开发过程中需要知道 git stash 的用法

目录1. git stash的应用场景2. 常用git stash命令2.1 git stash2.2 git stash save "message"2.3 git stash list2.4 git stash show2.5 git stash show -p2.6 git stash apply2.7 git stash pop2.8 git stash drop stash{num}2.9 git stash clear3. stash只会保存已…