【C#学习笔记】类型转换

在这里插入图片描述

文章目录

  • 类型转换
    • 字符转数字
      • GetNumericValue
      • Convert.ToInt32
      • 隐式转换计算
    • 字符串转数字
      • Parse 或 TryParse 方法
    • 字节数组转整数
  • as,is强制类型转换
    • is
    • as
  • 用户定义的转换


类型转换

我们简单地将值类型分为5种:整数型,浮点型,布尔型,字符型,再加上一个本属于引用类型的字符串。

由于 C# 是在编译时静态类型化的,因此变量在声明后就无法再次声明,或无法分配另一种类型的值,除非该类型可以隐式转换为变量的类型。

  • 隐式转换:由于这种转换始终会成功且不会导致数据丢失,因此无需使用任何特殊语法。 示例包括从较小整数类型到较大整数类型的转换以及从派生类到基类的转换。

  • 显式转换(强制转换) :必须使用强制转换表达式,才能执行显式转换。 在转换中可能丢失信息时或在出于其他原因转换可能不成功时,必须进行强制转换。 典型的示例包括从数值到精度较低或范围较小的类型的转换和从基类实例到派生类的转换。

上述2种转换就不过多赘述,隐式转换和显式转换都是十分基础的

  • 用户定义的转换:用户定义的转换是使用特殊方法执行,这些方法可定义为在没有基类和派生类关系的自定义类型之间启用显式转换和隐式转换。 有关详细信息,请参阅用户定义转换运算符。

  • 使用帮助程序类进行转换:若要在非兼容类型(如整数和 System.DateTime 对象,或十六进制字符串和字节数组)之间转换,可使用 System.BitConverter 类、System.Convert 类和内置数值类型的 Parse 方法(如 Int32.Parse)。 有关详细信息,请参见如何将字节数组转换为 int、如何将字符串转换为数字和如何在十六进制字符串与数值类型之间转换。

字符转数字

GetNumericValue

GetNumericValue是char类型提供的方法,用于将字符转换为double值的数字,失败则返回-1.0

令我不解的是,字符类型只能保存0~9之间的数字,不可能保存浮点数,不知为何返回值是double类型的。

public int a = 123;
char tmp;
tmp = a.ToString()[0];
char.GetNumericValue(tmp);// 使用char提供的GetNumericValue方法可以将char转为double的1

Convert.ToInt32

Convert类型的转换存在大量重载,基本可以应对所有转换情况

public int a = 123;
char tmp;
tmp = a.ToString()[0];
int b =Convert.ToInt32(tmp); // 使用ToInt32会将字符1转为ASCII码49

隐式转换计算

int a = 123;
char tmp;
tmp = a.ToString()[0];
int t = tmp - '0'; // 使用char类型进行计算,最后的结果类型是整数型,输出结果是ASCII码相减
// 49 - 48 = 1

字符串转数字

字符串转数字是一种比较万能的方法,因为object提供了ToString方法,能够让任何值类型都转化为字符串。

Parse 或 TryParse 方法

Parse 和 TryParse 方法会忽略字符串开头和末尾的空格,但所有其他字符都必须是组成合适数值类型(int、long、ulong、float、decimal 等)的字符。

char tmp = '1';
int a = Int32.Parse("  -105  "); // a = -105,无视空格
a = Int32.Parse(tmp.ToString()); // a = 1
bool b = Int32.TryParse("200", out a); // a = 200,方法本身返回布尔值,b = true

错误用法:

Int32.Parse("  -1.05  "); //浮点型不能用整型的Parse方法,应该为float.Parse或其他浮点型的Parse方法
Int32.Parse("  1 05  "); // 数字之间不能有空格
Int32.Parse(" 10e1 "); // 不接受科学计数法,

字节数组转整数

由于一般的整数类型Int的类型是System.Int32。而一个byte代表8位,所以一个Int32=4个字节,因此如果要字节转整数,一般需要四个四个地转变。

使用BitConverter类来操作字节数组

byte[] bytes = { 0, 0, 0, 25 };
// 此处是根据操作系统来决定字符顺序的
// 不同计算机的字节体系不同,可能高八位,可能低八位
if (BitConverter.IsLittleEndian)
    Array.Reverse(bytes);

int i = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("int: {0}", i);
// Output: int: 25

as,is强制类型转换

is

is 运算符检查表达式结果的运行时类型是否与给定类型兼容。 is 运算符还会对照某个模式测试表达式结果。

具有类型测试 is 运算符的表达式具有以下形式

E is T
E is not T

其中E是返回一个值的表达式,T是类型或类型参数的名称。 E 不得为匿名方法或 Lambda 表达式。

简单的来说,is判断true对应四种判断

  • ET 类型时
  • 当为T的派生类,子类,继承类(包括类和接口)时。
  • ET的可为空类型T?,且E不为空时
  • ET的转换涉及装箱拆箱时

让我们分别看看这四种对应的判断:

ET 类型时:

int a = 0;
if (a is int) // true
{
    Debug.Log(a);
}
if (a is long) // false
{
    Debug.Log(a);
}

当为T的派生类,子类,继承类(包括类和接口)时:

class Parent
{

}
interface IDonothing
{

}
class child : Parent, IDonothing
{

}
void Start()
{
    child c = new child();
    int a = 0;
    if (c is Parent) // true
    {
        Debug.Log(0);
    }
    if (c is IDonothing) // true
    {
        Debug.Log(1);
    }
}

ET的可为空类型T?,且E不为空时

int? a = null;
if (a is int) // a为int?但为空,false
{
    Debug.Log(1);
}
if (a is int?) // a为int?但为空,false
{
    Debug.Log(2);
}
int b = 1;
if (b is int) // b为int,true
{
    Debug.Log(3);
}
if (b is int?) // b为int,true
{
    Debug.Log(4);
}
a = 1;
if (a is int) // a为int?且不为空,true
{
    Debug.Log(5);
}
if (a is int?) // a为int?且不为空,true
{
    Debug.Log(6);
}

ET时涉及装箱拆箱时

object O;
int a = 1;
O = a;
if (O is int) // true
{
    Debug.Log(1);
}
if (O is int?) // true
{
    Debug.Log(2);
}
if (a is object) // true,毕竟object是所有类的父类,此时符合第二条E为T的派生类
{
    Debug.Log(3);
}

在检测类型时,is类型会对E类型进行T类型转换来判断是否为T类型,但不对E的本身的类型造成影响。但is类型不会考虑用户自定义的类型转换。


as

as运算符将表达式结果显式转换为给定的引用或可以为null值的类型。 如果无法进行转换,则as运算符返回null。 与强制转换表达式 不同,as运算符永远不会引发异常。

E as T

使用as运算符,与下述三目运算符是一样的:

E is T ? (T)(E) : (T)null

使用as进行转换,其中类型T必须是可为null值的类型
as 运算符仅考虑引用类型、可以为 null、装箱和取消装箱转换。 不能使用 as运算符执行用户定义的转换。 为此,请使用强制转换表达式。

object o = new object() as string;
o = "1";
Debug.Log(o.GetType()); // string类型

用户定义的转换

implicit operatorexplicit operator 关键字分别用于定义隐式转换或显式转换。 定义转换的类型必须是该转换的源类型或目标类型。 可用两种类型中的任何一种类型来定义两种用户定义类型之间的转换。

using System;
public readonly struct Digit
{
    private readonly byte digit;
    public Digit(byte digit)
    {
        if (digit > 9)
        {
            throw new ArgumentOutOfRangeException(nameof(digit), "Digit cannot be greater than nine.");
        }
        this.digit = digit;
    }
    public static implicit operator byte(Digit d) => d.digit;
    public static explicit operator Digit(byte b) => new Digit(b);

    public override string ToString() => $"{digit}";
}

public static class UserDefinedConversions
{
    public static void Main()
    {
        var d = new Digit(7);

        byte number = d;
        Console.WriteLine(number);  // output: 7

        Digit digit = (Digit)number;
        Console.WriteLine(digit);  // output: 7
    }
}

使用自定义类型可以定义隐式转换和显示转换,但是要注意类型匹配。

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

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

相关文章

增强型Web安全网关在银行的应用

销售,绝不是降低身份去取悦客户,而是像朋友一样给予合理的建议。你刚好需要,我刚好专业!仅此而已! 乔.吉拉德 健康的安全体系,还可以更完善 浙江某商业银行股份有限公司是一家成立多年的商业银行&#xf…

抖音seo源码开发源代码搭建分享

抖音SEO源码开发涉及到以下几个方面: 前端开发:包括抖音SEO页面的设计与布局,以及需要使用到的前端技术,如HTML、CSS、JavaScript等。 后端开发:包括抖音SEO页面的数据获取和处理,以及需要使用到的后端技术…

开源进展 | WeBASE v3.1.0发布,新增多个实用特性

WeBASE是一个友好、功能丰富的区块链中间件平台,通过一系列通用功能组件和实用工具,助力社区开发者更快捷地与区块链进行交互。 目前WeBASE已更新迭代至v3.1.0版本,本次更新中,WeBASE带来了最新的合约Java脚手架导出功能&#xff…

数字电路的重要概念——静态功耗和动态功耗

静态功耗和动态功耗: CMOS电路功耗是由静态功耗和动态功耗组成的,动态功耗远大于静态功耗 1:静态功耗: 我们从一个简单的反相器角度来理解和说明静态功耗的概念,众所周知,反相器是由PMOS和NMOS互补组成的…

当服务器域名出现解析错误的问题该怎么办?

​  域名解析是互联网用户接收他们正在寻找的域的地址的过程。更准确地说,域名解析是人们在浏览器中输入时使用的域名与网站IP地址之间的转换过程。您需要站点的 IP 地址才能知道它所在的位置并加载它。但,在这个过程中,可能会出现多种因素…

关于游戏的笔记

关于搭建秦时明月2一键端,并且开启秘境神秘商人东海寻仙幻化 1.该游戏下主要的目录 gm端 服务框架 服务端 2.修改对应的文件 C:\qs\Q2Server\server\conf_common\ManagerAddress.xmlC:\qs\Q2Server\server\conf_manager\GateServer.xml修改ip 3.启动gm startup…

HTML 是什么?它的全称是什么?

聚沙成塔每天进步一点点 专栏简介HTML是什么?HTML的全称是什么?写在最后 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对We…

【项目管理】PMP备考宝典-第一章《引论》

文章目录 第一节:项目管理的意义1.什么是项目2.项目管理的前世今生3.项目管理与战略的关系4.组织管理模式的转型升级5.推动项目管理普及的力量 第二节:项目管理的逻辑1.项目管理目标的演变2.项目与运营的关系3."人-过程-环境"三个领域的关系4.…

Sencha Ext.NET Crack 快速应用程序的正确工具集

Sencha Ext.NET Crack 快速应用程序的正确工具集 Sencha Ext.NET是一个高级的ASP.NET核心组件框架,它包含了强大的跨浏览器Sencha Ext JS库。通过140多个预构建和专业测试的UI组件实现企业级性能和生产效率。Sencha Ext.NET使用尖端的Web技术创建功能强大的Web应用程…

反弹shell的N种姿势

预备知识1. 关于反弹shell 就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell与telnet,ssh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。2. 反弹shel…

JavaScript学习(3)

Web API 是开发人员的梦想。 它可以扩展浏览器的功能它可以极大简化复杂的功能它可以为复杂的代码提供简单的语法 什么是 Web API? API 指的是应用程序编程接口(Application Programming Interface)。 Web API 是 Web 的应用程序编程接口…

YOLOv5基础知识入门(2)— YOLOv5核心基础知识讲解

前言:Hello大家好,我是小哥谈。YOLOV4出现之后不久,YOLOv5横空出世。YOLOv5在YOLOv4算法的基础上做了进一步的改进,使检测性能得到更进一步的提升。YOLOv5算法作为目前工业界使用的最普遍的检测算法,存在着很多可以学习…

西瓜书读书笔记整理(五)—— 第四章 决策树

第四章 决策树 4.1 基本流程4.1.1 什么是决策树算法4.1.2 决策树学习的目的4.1.3 决策树学习基本过程4.1.4 决策树学习基本算法4.1.5 递归结束的三种情况 4.2 划分选择4.2.1 信息增益(information gain)—— ID3 决策树学习算法属性划分准则4.2.2 信息增…

JUC之线程中断与LockSupport

什么是中断 首先一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。其次在Java中没有办法立即停止一条线程,然而停止线程却显得尤为重要,如取消一个耗时操作。因此,Java提供了一种用于停止线程的机制——中…

力扣 -- 467. 环绕字符串中唯一的子字符串

一、题目 二、解题步骤 下面是用动态规划的思想解决这道题的过程&#xff0c;相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 三、参考代码 class Solution { public:int findSubstringInWraproundString(string s) {int ns.size();vector<int> dp(n,1);int re…

Godot 4 源码分析 - 增加格式化字符串功能

Godot 4的主要字符串类型为String&#xff0c;已经设计得比较完善了&#xff0c;但有一个问题&#xff0c;格式化这块没怎么考虑。 String中有一个format函数&#xff0c;但这个函数只有两个参数&#xff0c;这咋用&#xff1f; String String::format(const Variant &va…

vue 新学习 06 js的prototype ,export暴露,vue组件,一个重要的内置关系

部分内容参考的这篇文章 原文链接&#xff1a;https://blog.csdn.net/harry5508/article/details/84025146 写的很好。 01 在js中&#xff1a; 原型链 注意&#xff1a;构造函数.prototype实例化对象.__proto__&#xff0c;都是指向函数的原型。 export&#xff1a; -export用…

Popover气泡卡片(antd-design组件库)简单使用

1.Popover气泡卡片 点击/鼠标移入元素&#xff0c;弹出气泡式的卡片浮层。 2.何时使用 当目标元素有进一步的描述和相关操作时&#xff0c;可以收纳到卡片中&#xff0c;根据用户的操作行为进行展现。 和 Tooltip 的区别是&#xff0c;用户可以对浮层上的元素进行操作&#xff…

项目实战 — 消息队列(5){统一硬盘操作}

前面已经使用数据库管理了交换机、绑定、队列&#xff0c;然后又使用了数据文件管理了消息。 那么&#xff0c;这里就创建一个类&#xff0c;讲之前的两个部分整合起来&#xff0c;对上层提供统一的一套接口&#xff0c;表示硬盘上存储的所有的类的信息。 /* * 用这个类来管理…

【Linux】Linux下git的使用

文章目录 一、什么是git二、git发展史三、Gitee仓库的创建1.新建仓库2.复制仓库链接3.在命令行克隆仓库3.1仓库里的.gitignore是什么3.2仓库里的git是什么 三、git的基本使用1.将克隆仓库的新增文件添加到暂存区(本地仓库)2.将暂存区的文件添加到.git仓库中3.将.git仓库中的变化…