Microsoft.NET 框架程序设计 —— 基元类型、引用类型与值类型

        本文讨论.NET 框架开发人员经常遇到的各种数据类型。熟悉这些类型的不同行为对于一个开发人员来说至关重要。当我刚开始接触.NET框架时,就没有完全理解基元类型、引用类型和值类型之间的一些差别。这种模糊的认识甚至无意间导致了一些难以査找的bug以及性能问题。我希望通过本章的解释,能够帮助大家在提升代码效率的同时避免我曾遇到的一些麻烦。

5.1 基元类型

        某些数据类型的使用非常频繁,许多编译器都允许我们用某种简化的语法来操作它们。例如,我们可以用下面的语法来分配一个整数:

        System.Int32 a=new system.Int32();

        相信大家都会感到用这样的语法来声明和初始化一个整数未免太过麻烦。所幸,许多编译器(包括C#)都允许我们使用类似下面的语法来对整数进行声明和初始化:

        int a =0;

        这种语法大大提高了代码的可读性,并且经编译后和前一种语法生成的是同样的儿代码。编译器直接支持的数据类型称为基元类型(primitive type)。

        基元类型和.NET 框架类库(FCL)中的类型有直接的映射关系。例如,在#中,int直接映射为System.Int32 类型。因此,下面4行代码都能通过编译,并产生同样的I代码:

int a=0;                            //最便捷的语法
System.Int32 a=0;                   //较便捷的语法
int a= new int();                   //不便捷的语法
System.Int32 a=new System.Int32();  //不便捷的语法

        表5.1显示了FCL中的类型和它们在C#中对应的基元类型。对于那些和通用语言规范(CLS)兼容的类型,其他开发语言也都提供了类似的基元类型。但对于那些与CLS不兼容的类型,则无此必要。

表5.1 FCL类型及其在 C#中对应的基元类型

C#中的基元类型FCL 类型是否与 CLS 兼容描 述
sbyteSystem.SByte有符号8位值
byteSystem.Byte无符号8位值
shortSystem.Intl 6有符号16位值
ushortSystem.UInt16无符号16位值
intSystem.Int32有符号32位值
uintSystem.UInt32无符号32位值
longSystem.Int64有符号64位值
ulongSystem.UInt64无符号64位值
charSystem.Char16 位 Unicode 字符(不像非托管 C++中那样,char表示的是一个8位值)
floatSystem.SingleIEEE32位浮点数
doubleSystem.DoubleIEEE 64位浮点数
boolSystem.Boolean一个 True 或者 Flase值
decimalSystem.Decimal128位高精度浮点值,通常用于不容许有舍入误差的金融计算场合。在这128位中,1位表示浮点值的符号,96位表示浮点值本身(译注:一个整数值,小数点位置由下面8个位来确定),8位表示用96位值除以浮点值所得结果的10的幂次(幂次范围为0~28)。其余的位尚未使用
objectSystem.Qbiect所有类型的基类型
stringSystem.String一个字符数组

         C#语言规范声称“作为一种编码风格,使用关键字应该优于使用完整的系统类型名称”。我个人不同意这段论述。我更喜欢使用FCL类型名,并且完全避免使用基元类型名称。实际上,我希望编译器甚至不要提供基元类型名称,并强制开发人员使用FCL类型名。理由如下:

  • 我发现很多开发人员都困惑于不知在代码中使用string还是 String。因为 C#中的 string(关键字)实际上映射了 System.String(FCL 类型),所以两者之间没有任何不同,都可以使用。
  • 在C#中,long 映射为 System.Int64,但是在其他的编程语言中,long 可能映射为一个 Int16或者 Int32。实际上,托管扩展 C++将 1ong看作是一个Int32。如果习惯了在一种语言下编程,再转而去阅读用另一种语言编写的代码就很容易误解其中的意图。实际上,大多数语言甚至不将 long 看作是关键字,也不会编译使用它的代码。
  • FCL,中有很多类型的方法都将一些类型名作为方法名称的一部分。例如,BinaryReader 类型就提供了诸如 ReadBoolean、ReadInt32、ReadSingle 之类的方法;而 System.Convert 类型也提供了诸如 ToBoolean、ToInt32、ToSingle 之类的方法。虽然下面的代码是合法的,但其中含有float的代码行在我看来总有些不自然,这段代码的正确性也并不明显:

BinaryReader br=new BinaryReader(...);

float val=br.ReadSingle();        //正确,但是有些不自然

Single val= br.Readsingle();    //正确,并且感觉也很自然

因为上面所有这些原因,本书将通篇采用FCL类型名。

在许多编程语言中,我们可能希望下面的代码能够正确地编译并执行:

Int32 i= 5;   //一个32位的值
Int64 l=i;    //隐式转型为一个64位的值

        大家可能会认为这段代码不能通过编译。毕竟,System.Int32和 System.Int64是不同的类型。但是,我们可能会很高兴看到C#编译器能够正确地编译这段代码,并且能够按我们的预期运行。为什么呢?

        这是因为 C#编译器熟悉基元类型,并且在编译代码时会应用自己的规则。换句话说,我们所选的编译器能够识别一些通用的编程模式,并产生必要的几,指令来使代码按期望的方式运行。

具体而言,编译器一般会支持和类型转换、文本常量(1iterals)、操作符相关的一些模式。看下面的例子。

        首先,编译器能够在基元类型之间进行隐式或者显式的转型:

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

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

相关文章

【QT】实时语言切换

前言:一个完整的软件开发通常需要支持多种语言,本文主要讲述实时语言切换开发时的相关解决方案。 1. 制作字库文件 添加标识 在需要被翻译的字符串前面标识tr,如QString str=tr(“hello,world!”); ,这很重要&#xf…

使用 Django Rest Framework 构建强大的 Web API

文章目录 安装 Django Rest Framework创建序列化器创建视图和 URL 路由配置认证和权限测试 API Django Rest Framework(DRF)是一个强大的工具,用于在 Django Web 框架中构建灵活且功能丰富的 Web API。它提供了许多功能,包括序列化…

ubuntu22.04 kubeadm安装k8s集群(从零到有)

ubuntu kubeadm安装k8s集群 前言一、初始化所有ubuntu服务器二、安装kubeadm三、kubeadm初始化节点、加入集群四、安装kubesphere1、下载yaml文件2、运行apply报错3、安装完成。4、忘记密码,强制修改5、Kubesphere其他组件安装前言 k8s 三master 三node所有节点hosts文件添加…

android radiongroup应用举例

android radiongroup应用举例 在 Android 中,RadioGroup 是一个特殊的布局容器,用于包含多个 RadioButton 控件。这些 RadioButton 通常一起使用,以便用户可以从一组选项中选择一个。当用户选择其中一个 RadioButton 时,其他 Rad…

(六)DockerCompose安装与配置

DockerCompose简介 Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。使用前面介绍的Dockerfile我们很容易定义一个单独的应用容器。然而在日常开发工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现…

线性回归分析

线性回归分析是统计学和数据分析中常用的一种工具,它研究的是因变量与自变量之间的线性关系。在实际应用中,线性回归可以帮助我们理解变量之间的关联,预测未来的趋势,以及进行决策支持。在本选题中,我们将深入探讨线性…

protobuf学习

学习了下protobuf这个工具,可以用来序列化数据结构,而且效率很高,数据可以压缩的更小。 记录下,我这里主要在C#里使用,从NuGet程序包安装以下两个 安装好后可以在该程序目录找到 packages\Google.Protobuf.Tools.3.26.…

在windows中使用wsl下的unbuntu环境

1 unbuntu下载编译环境 编译环境安装命令: sudo apt install gdb sudo apt install gcc sudo apt install g 2 使用vscode正常打开项目,在window中打开的项目(官方推荐将项目放在linux中的home目录) 但在windows中也可以使用&a…

汐鹤Key码查询,网站授权系统源码

汐鹤Key码查询和网站授权系统源码主要用于特殊虚拟物品销售商家。 下 载 地 址 : runruncode.com/php/19770.html 附带插件功能(网站授权),但目前开发内容较少,请谅解!同时,代码优化空间很大…

【软考】设计模式之装饰器模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. 适用性6. 优点7. 缺点8. java示例 1. 说明 1.动态地给一个对象添加一些额外的职责。2.Decorator Pattern。3.就增加功能而言,装饰器模式比生成子类更加灵活。4.一种在不改变现有对象结构的情况下,动态地给对…

Office VBA基础 学习笔记

Office VBA基础 一、引言 VBA(Visual Basic for Applications)作为office内置的一种编程语言,在自动化办公、数据处理、表单开发等方面发挥着越来越重要的作用。VBA不仅允许用户定制Office应用程序的行为,还能与各种数据库、Web…

垃圾溢满堆放识别检测

垃圾溢满堆放识别检测系统的核心技术是基于YOLO深度学习模型,垃圾溢满堆放识别检测系统能够在监控画面中快速识别出垃圾箱外部的垃圾堆放情况。系统经过大量的训练和优化,能够识别出各种垃圾的特征,并能够准确判断是否溢满堆放。垃圾溢满堆放…

【MySQL精通之路】InnoDB(9)-表和页压缩(1)-表压缩

目录 1.表压缩概述 2.创建压缩表 2.1 在FPT表空间中创建压缩表 2.2 在通用表空间中创建压缩表 2.3 压缩表的限制 3.优化InnoDB表的压缩 4.运行时监控InnoDB表压缩 5.InnoDB表的压缩工作原理 5.1 压缩算法 5.2 InnoDB数据存储和压缩 5.3 B树页面的压缩 5.4 压缩BLOB…

Android HAL Service开发总结

Android HAL Service开发总结: 1.需要针对自己的hwservice编写init.rc启动脚本 vendor.device.xxx_hwfunservice-1.1.rc service vendor.device.xxx_hwfunservice-1.1 /vendor/bin/hw/vendor.device.xxx_hwfun1.1-serviceclass haluser systemgroup systemseten…

鸿蒙OS开发:【一次开发,多端部署】(多设备自适应能力)实例

多设备自适应能力 介绍 此Demo展示在JS中的多设备自适应能力,包括资源限定词、原子布局和响应式布局。 效果预览 使用说明 1.本示例中的资源限定词和响应式布局针对常见设备类型做了适配,可以在预览器中开启"Multi-profile preview"进行多…

【Day7:JAVA面向对象的初级使用】

目录 1、类和对象1.1 类的介绍1.2 类和对象的关系1.3 类的组成 2、对象内存图2.1 单个对象内存图2.2 两个对象内存图2.3 两个引用指向相同内存图 3、成员变量和局部变量3.1 成员变量和局部变量的区别 4、this关键字4.1 this可以解决的问题4.2 this介绍4.3 this内存图4.4 this总…

MapReduce基础实战

**MapReduce基础实战** 一、引言 随着大数据时代的到来,数据量的快速增长对数据处理能力提出了更高的要求。MapReduce作为一种分布式计算框架,以其高效、容错和易于编程的特点,成为了处理大规模数据集的重要工具。本文将介绍MapReduce的基本…

浏览器输入URL到网页显示之间发生了什么

记: DNS(Domain Name System,域名系统)就是根据域名来查找对应的IP地址的一个关键系统。 域名层级关系: 根域名服务器(.)顶级域名服务器(.com)权威域名服务器(server.com) 首先浏…

5.22R语言初步学习-2(使用包、绘图)

本文逻辑可能有些凌乱,是在数据处理的使用中学习R语言,所以用到的一些包、函数等都直接写在这了,主要就是处理数据的一个过程可能会用到的部分函数。 包的使用 R语言的使用,很大程度上是借助各种各样的R包的辅助,从某…

Python 之程序截图常见的几种方式

pywin32 PyQt5 需要先 pip 安装 pywin32、PyQt5 ,相关依赖 pip 会自动安装。 pip install pywin32 pip install PyQt5 下面这种方式比较强悍,可以根据活跃窗口的 title 名称,自动找到对应的窗口然后进行截图。 import sysimport win32gu…