解读经典《C#高级编程》第七版 Page32-38.核心C#.Chapter2
前言
接下来讲讲预定义数据类型。关于数据类型,其实是非常值得透彻研究的。
01
预定义数据类型
值类型和引用类型
C#将把数据类型分为两种,值类型和引用类型,值类型存储在堆栈上,引用类型存储在托管堆上。因此,对于值类型,如果:
Int a = 1;
Int b = a;
那么内存中就有两份的值1。
而对应引用类型,如果:
User userA = new User();
User userB = userA;
那么内存中只有一份User对象,userA和userB都指向它。
需要提到一句的是,结构(struct)是值类型,虽然我从来没有用到,但在需要极致优化性能的时候,可能是用的上的。
这基本上是大家都知道的。但在实际使用中,这种所谓的引用关系会比较隐秘,造成我们使用引用类型上的一些问题,所以我们需要更深入的讲一讲。
CTS类型(Common Type System)
CTS类型是.Net Framework的类型,而不是C#的类型,即我们之前讲到,CLR也是高度对象化的。在CLR层面规定了通用的类型,这样不同的开发语言比如C#,VB.Net才能良好的融合。比如Int32,Int64就是.Net框架的结构。我们定义一个Int和long既可以写为:
int val = 10;
long val2 1000;
也可以写为:
Int32 val = 10;
Int64 val2 = 1000;
当然我们实际使用中不会像后者那么用。
我们还可以发现,Int32,Int64是结构(struct),是值类型,所以这种类型通用化对.Net框架的性能的影响极小。
预定义的值类型
预定义的值类型有:
整数:
浮点数:
基本类型在赋值时,可以使用后缀(可大写或者小写)明确指定类型,比如:
Long val1 = 10L;
float val2 = 12.3F;
对于整数类型,如果不明确指定类型,系统会默认为int,而对于浮点数类型,不明确指定时系统默认为double。
我曾经很疑惑的是,既然这么说,是不是在初始化的时候一定要这么指定后缀呢?毕竟初始化基本类型是比较常见的操作。而我现在认为,非特殊情况下,基本上是不需要的。事实也是如此,我们很少见到有这么写的。比如对于:
Long val1 = 10L; 和 Long val1 = 10;
效果是一样的。因为val1定义为long,作为int的10会自动向上转型为long,不会有精度损失。而对于:
float val2 = 12.3F; 和float val2 = 12.3; 有没有区别呢?是有的,因为后面这句赋值语句有错误,不能通过编译,因为作为double的12.3转化为float,是有精度损失的,所以要么你强制转换,要么你加F。
所以我们会发现,你写一个对基础类型的赋值语句,你能写出来,且编译器没提示错误,就是没问题的;不能写的,编译器会提醒你。编译器已经足够智能,不需要担心要不要加后缀的问题。
Decimal类型:
Decimal是个很重要的类型,我在实际项目中,从来没有用过float和double,因为它们有精度问题,我都是要么整数(用于数量),要么Decimal(用于价格,金额等)。.Net把它称为“用于财务计算的专用类型”。我们对比Java会发现,Java的高精度计算类型是一个叫做BigDecimal的普通类,它的初始化要用比如new BigDecimal(10)这种类创建的方式来实现。而在C#中将其地位提升为预定义类型。但同时,书中也强调,Decimal仍然不是“基本类型”,我们可以认为,它的本质和Java的BigDecimal是一样的,只是将其“模拟”为基本类型,这样使用更便捷,但它的计算实际上仍然会有性能损失。
Bool类型:
字符类型:
字符类型,有多种表示方式:
char val1 = 'A'; //字面量
char val2 = '\u0041'; //Unicode
char val3 = (char)65; //int转换
char val4 = '\x0041'; //16进制
字符常用的还有用“转义符”(反斜杠\)表示的特殊字符,比如换行符\n,回车符\r等。
预定义的引用类型
预定义引用类型的概念太重要了,因为它是.Net整个类结构的基础。
上图的每个字都值得分析。我们注意到,object类型被叫做“根类型”,它是包括值类型的所有其他类型的父类型。为什么值类型也是?因为值对象可以被“装箱”并放入托管堆而成为引用对象,而装箱又导致拆箱,这是非常重要的概念,对这个概念理解的不好,会写出意想不到的复杂代码。
而String类型的概念是:Unicode字符串,也很重要,这说明什么,说明字符乱码问题得到了彻底解决,一个英文和一个中文字符长度相同,等等。String类型是个非常特殊又奇怪的类型,它是引用类型,但它的行为又像值类型,这是特意设计的,因为字符串的使用太普遍了,而值类型的概念比引用类型使用起来更直观和简单。它的几个特点:
- String对象是引用类型,它被分配在堆上,而不是栈上
- 因此,当把一个字符串变量赋予另一个字符串时,会得到对内存中同一个字符串的两个引用
- 字符串是不可改变的。修改其中一个字符串,就会创建一个全新的String对象,而另一个字符串不发生任何变化
有了以上特性,我们可以看到值类型的行为了:当赋予一个不同的字符串值,系统总给你new一个字符串新值;而当你赋值已有的某个字符串时,系统从堆中给你找出来赋值给你。这样既保证了值类型的行为,也优化了引用类型的性能,是一种平衡的好方案。当然在某些场景下,String的这种特性也会导致性能问题,比如在for循环中拼接一个字符串,这个时候简单的用赋值语句改变String时,就会导致一直创建新的字符串,性能大降,所以这个时候我们常常会用StringBuilder来构造字符串。
字符串中,常碰到转义符的问题,字符串中的\将被理解为转义符,怎么让C#不将其理解为转移符呢?“将转义符再转义”,即再加\,比如一个目录路径表示为:
string path = “C:\\windows\\Temp”;
我们可以简化这种写法为:
string path = @“C:\windows\Temp”;
@不仅是用于描述路径,还用于其他多种场景,这会让人混淆,@有没有可明确描述的效用?有的,它的功能可通用性的描述为:在这个@后的所有字符都看作是其原来的含义。比如上面的路径例子,原来的含义就是\就是路径的表述,而不是转义符的意思。还有比如@用在字符串换行中:
string path = @“华为是
中国的骄傲”;
当没有@时,字符串在输入中换行会导致编译错误,因为回车换行在语言规范中有特殊含义,加了@表示告诉编译器,“我这字符串中的换行符就是原本的换行的意思,你不用特殊解释”。
其他所有用@的场景,都可以如此解释,这是一种可通用的解释。
预定义类型内容非常长,就先讲到这里,下一篇我们讲流控制。
觉得文章有意义的话,请动动手指,分享给朋友一起来共同学习进步。
欢迎关注本人微信公众号,更及时的关注最新文章(每周三篇原创文章,以及多篇专题文章):
附文:
C#的两种类据类型:值类型和引用类型
C# String与StringBuilder
上一篇:解读经典《C#高级编程》第七版 Page20-32.核心C#.Chapter2
转载于:https://www.cnblogs.com/holyknight17/p/10183767.html
解读经典《C#高级编程》第七版 Page32-38.核心C#.Chapter2相关推荐
- ASP.NET MVC 4高级编程(第4版)
<ASP.NET MVC 4高级编程(第4版)> 基本信息 作者: (美)Jon Galloway Phil Haack Brad Wilson K. Scott Allen 译者: 孙远 ...
- Android 4高级编程(第3版)》
<Android 4高级编程(第3版)> 基本信息 原书名:Professional Android 4 Application Development 作者: (英)Reto Meier ...
- Android 4高级编程(第3版)
<Android 4高级编程(第3版)> 基本信息 原书名:Professional Android 4 Application Development 作者: (英)Reto Meier ...
- 《UNIX环境高级编程(第3版)》
<UNIX环境高级编程(第3版)> 基本信息 原书名:Advanced Programming in the UNIX Environment (3rd Edition) (Addison ...
- python权威指南 pdf_Python高级编程(第2版) 中文完整pdf扫描版[76MB]
Python作为一种高-级程序设计语言,凭借其简洁.易读及可扩展性日渐成为程序设计领域备受推崇的语言之一. Python高级编程(第2版)基于Python 3.5版本进行讲解,通过13章的内容,深度揭 ...
- Linux - Unix环境高级编程(第三版) 代码编译
Unix环境高级编程(第三版) 代码编译 本文地址:http://blog.csdn.net/caroline_wendy 时间:2014.10.2 1. 下载代码:http://www.apuebo ...
- 《Android 4高级编程(第3版)》(完整书签).pdf
下载地址:网盘下载 内容简介 编辑 <Android 4高级编程(第3版)>由Android权威专家编写,涵盖了所有最新的内容,是学习使用Android 4 SDK开发移动应用程序的理想指 ...
- android高级编程新浪,《C高级编程(第4版)》-完整教材教程
崇仁不畅陌生丽台怪声礼物两可.寰球撬杠倡导搏击电星新盘蒙住<C高级编程(第4版)>-完整教材教程,胚柄抽空绿化些微两路.恸哭浅山转折乐华被迫党员心咒.国网茶荷前镇鬼物奶羊,全班柳铁路遥橱窗 ...
- UNIX环境高级编程(第三版 源码及编译好的静态库文件)
UNIX环境高级编程(第三版) 源码 及 库文件 链接: https://pan.baidu.com/s/1tPY17lWNDEbzkOwZaRUUNg 提取码: 1024 复制这段内容后打开百度网盘 ...
- UNIX环境高级编程-第三版
Unix环境高级编程-第三版 之前学习了<Linux系统编程>对于常见的概念和函数都有了基础的认知,这里准备通过这本书,深入学习系统API相关内容.笔记内容会有所倾向,不会严格反应书本内容 ...
最新文章
- C语言函数怎么像python那样返回多个值?(三种方法:1、设置全局变量 2、传递指针 3、使用结构体返回不同类型的数据)
- python中的轻量级定时任务调度库:schedule
- 计算机二级怎么测试c语言,全国计算机等级测试二级C语言视频教程(完整版).doc...
- 计算机u打字,win7电脑打字打不出来怎么办
- C++ —— C++数据类型
- nosuiteable Oracle,快给你的Kubernetes集群建一个只读账户(防止高管。。。后)
- MySQL建表规范与常见问题
- Apache Flink 在斗鱼的应用与实践
- 适合点播应用的P2P加速系统
- fiddler 手机代理上网 通过代理服务器进行身份验证失败
- HP喷墨打印机真空加墨的方法
- 【R语言爬虫】R语言提交post请求抓取盈盈理财数据
- 海明码检错与纠错,经典例子讲解~
- VB.net学习笔记(六)VB.net的对象
- 剑灵服务器延迟时间在哪看,剑灵怎么看延迟,剑灵怎么看延迟?剑灵游戏看延迟通用方法...
- Mysql服务端(三)--- 索引及设计建议
- WPF 设置纯软件渲染
- spring 事务传播
- 【Swing入门教程】一步一步做Netbeans(1):类Netbeans的主界面
- 大数据架构师——数据湖技术(二)
热门文章
- 计算机除法用什么函数,“excel除法函数公式是哪个“excel中公式或者函数怎么用呢?谢谢...
- 短视频的内容付费模式
- 公众号怎么关联多个不同主体的小程序详细教程
- 淘晶驰+arduino控制步进电机
- Deepin Linux 安装开启Telnetd、telnet
- 黄金投资技术分析入门的时候要学点什么
- 毕业生自曝大学4年花费达84万 交女友花15万
- 客户管理信息系统html,一个简易的客户管理信息系统
- 如何选择KNN的最合适的K值
- 英特尔携手爱立信打造全球Cloud RAN技术中心