类型的划分##

       一个类型,要么是值类型,要么是引用类型。区别在于拷贝方式:值类型拷贝值,引用类型拷贝引用

值类型###

       值类型直接包含值。相当于每一个值类型都有自己单独的值:

int a = 10;
int b = a;

a和b都有着自己的值,修改a并不会影响b,反过来一样,互不影响。

       即使是将实例传给Console.WriteLine()这样的方法也会产生内存拷贝。由于值内存需要创建内存拷贝,因此定义的时候不要让它们占用太多内存。

引用类型###

       引用类型的变量存储对数据存储位置的引用,而不是直接存储数据。也就是说,要到对应的位置才能找到真正的数据。因此为了访问数据,“运行时”要先从变量中读取内存位置,再“跳转”到包含数据的内存位置。引用类型指向的内存区为成为堆。

       正如前面所说,引用类型拷贝引用,它不包含值,每次引用变量的赋值都是引用的拷贝,并不需要拷贝数据。

       值得注意的一点,引用类型只复制对数据的引用,所以两个不同的变量可引用相同的数据。在这种情况下,只要数据发生了改变,就会影响到所引用到他的变量的值,毕竟都是引用同一个数据。

可空修饰符##

       我之前提到过null值,它是给引用变量表示为空的值,一般不能将它赋值给值类型。根据定义,值类型不能包含引用。但是有的时候我们的确又有这一方面的需求,所以为了声明能存储null变量,要使用可空修饰符"?"。示例:

int? cnt = null;

隐式类型的局部变量##

    关键字:var,用于声明隐式类型的局部变量。示例:

var text = Console.WriteLine();

这么做最终的CIL代码并没有区别,但var告诉编译器根据声明时所赋的值来推断数据类型。

    虽然允许用var取代像是数据类型,但是在已知数据类型的情况下还是不要这么做,明确的声明数据类型不仅能够增加可读性,还相当于亲自确认了等号右边返回的是你所需要的数据类型。

    匿名类型能够在方法内部动态声明数据类型,并不需要通过显式的类定义来声明,示例:

var people1 = new { Name = "Van", Say = "啊?" };
var people2 = new { Name = "Bili", Say = "乖乖站好" };
System.Console.WriteLine( $"{people1.Name} {people1.Say}");
System.Console.WriteLine( $"{people2.Name} {people2.Say}");

元组##

    有时候需要合并数据元素。元组正好可以解决这个问题,它允许在一个语句内完成所有变量的赋值。

    以下是它的语法形式:

    将元组赋给单独声明的变量:

(string power, string name, int weight) = ("超高校的幸运", "脖子直抖", 65);

    将元组赋给预声明的变量:

string power, name;
int weight;
(power, name, weight) = ("超高校的幸运", "脖子直抖", 65);

    将元组赋给隐式类型的变量:

var (power,name,weight) = ("超高校的幸运", "脖子直抖", 65);

注意:此处以及下面包含的 var 绝不能如果替换成显示类型(如string或int)。因为元组宗旨是允许每一项都有不同的数据类型,所以每一项都指定同一个显示类型名称和这个宗旨冲突,即便是真的一样,编译器也不允许指定显示类型。

    声明具名元组,将元组值赋给它。

(string power, string name, int weight) people = ("超高校的幸运", "脖子直抖", 65);

    声明包含具名元组项的元组,将其赋给隐式类型的变量。

var people = (power:"超高校的幸运", name:"脖子直抖", weight:65);

    将元组项未具名的元组赋给隐式类型的变量,再通过向编号属性访问单独的元素。

var people = ("超高校的幸运", "脖子直抖", 65);
people.Item1;//people.Item2;

若是具名元组还是可以通过项目编号属性访问单独的元素。

    赋值时用下划线丢弃元组的一部分数据(弃元)。

(string power, _, int weigth) people = ("超高校的幸运", "脖子直抖", 65);

数组##

    数组能够在单个变量中存储同一种类型的多个数据项,并且可以通过索引来单独访问这些数据项。数组的数据线索引从0开始,最大索引值总是比数组中的数据项少1。但是现在大多数程序都使用泛型集合类型而非数组来存储数据集合。

数组声明###

    数组声明,直接上代码:

string[] arr1;

方括号在数据类型之后,变量名之前。

    声明二维数组的方法,代码:

string[,] arr2;

在用逗号进行多维数组的声明,总共维数等于逗号加一。

数组的实例化和赋值###

    数组可在声明的同时初始化,例如:

string[] arr3 = {"1","1","4","5","1","4"};

元素的下标对应就是对应元素的位置,依次排列。

    也可以先声明数组再进行赋值,如下:

string[] arr4;
arr4 = new string[]{"1","1","4","5","1","4"};

但是从C#3.0开始就不必在new之后指定数组类型。编译器能根据初始化列表中的数据类型推断数组类型。如下:

arr4 = new []{"1","1","4","5","1","4"};

上面使用了new关键字,它指示“运行时”为数据库类型分配内存,也就是实例化数据类型。

    我们也可以给数组分配固定大小但不提供初始化,也可以指定大小并赋值,如下:

string[] arr5 = new string[6]{"1","1","4","5","1","4"};

    数组在没有被初始化的时候,“运行时”会给每个元素初始化为他们的默认值:

  • 引用类型会被初始化为null。
  • 数字类型会被初始化为0。
  • bool初始化为false。
  • char类型初始化为\0。

    多位数组注意不要超出对应的声明范围,这里不再讨论。

数组的使用###

    可以用方括号表示法(数组访问符)来访问数组中一个特定的数据项。注意下标是从0开始的,最大下标是数组内容减一。

arr1[1];//表示arr1数组中第二个元素的内容

    二维数组同理。

    交错数组,也就是数组数组,用数组来存储数组,声明方式如下:

int[][] arr6 = {
new int[]{1,1,1};
new int[]{2,2,2};
new int[]{3,3,3};
}

    当然数组也有一些方法,下面进行举例:

  • arr.Length:获取数组的长度,只读。

我们在访问数组的边界元素时,一般会采取Length-1这样的方式来访问数组边界成员。

  • System.Array.Sort():对数组内容进行排序。
  • System.Array.BinarySearch(var[] arr, var searchString):返回搜索值的索引,不存在就返回-1。前提是按升序排序。
  • System.Array.Clear(intArray, 0, intArray.Length):清空第0到第intArray.Length个索引的元素(置零)。
  • System.Array.Reverse(arr):反转数组顺序。

还有众多方法,这里不一一列举,看个乐呵。

字符串作为数组使用###

    我们需要注意的是,字符串是不可变的,字符串作为数组使用时,我们访问到的成员变量都是char类型的变量。为此将字符串作为数组使用时要注意不能去修改成员变量的内容。

小结##

    本次博文的内容介绍了更多的数据结构,但是这也只是开始,介绍了值类型,引用类型,隐式类型,元组以及数组,这些内容都会贯彻到我们今后的项目之中,一定要打好坚实的基础,当然不是说要背下来,理解到位才是我们应该去做的。

C#深入浅出之更多数据类型的更多相关文章

  1. 【Python】 更多数据类型collections&简易数据文件shelve

    ■collections collections在python内建的数据类型基础上新增一些实用的数据类型,其目的在于增加代码的可读性?(虽然我自己没怎么用过..) ① deque 双端队列 q = d ...

  2. 泛函编程(26)-泛函数据类型-Monad-Applicative Functor Traversal

    前面我们讨论了Applicative.Applicative 就是某种Functor,因为我们可以用map2来实现map,所以Applicative可以map,就是Functor,叫做Applicat ...

  3. Redis简介、与memcached比较、存储方式、应用场景、生产经验教训、安全设置、key的建议、安装和常用数据类型介绍、ServiceStack.Redis使用(1)

    1.NOSQL简介 nosql的产生并不是要彻底的代替关系型数据库,而是作为传统关系型数据库的一个补充. Facebook和360使用Cassandra来存储海量社交数据 Twitter在其url抓取 ...

  4. 以太坊智能合约 Solidity 的常用数据类型介绍

    目录 目录 1.数组 1.1.对数组的增删改查操作. 2.String.Bytes.Mapping的使用 3.Enums 和 Structs 的简单应用 4.Ether 单位和 Time 单位 5.A ...

  5. python学习日记(基础数据类型及其方法01)

    数字 int 主要是用于计算的,常用的方法有一种 #既十进制数值用二进制表示时,最少使用的位数i = 3#3的ASCII为:0000 0011,即两位 s = i.bit_length() print ...

  6. 深入浅出的webpack4构建工具--webpack4+vue+vuex+mock模拟后台数据(十九)

    mock的官网文档 mock官网 关于mockjs的优点,官网这样描述它:1)可以前后端分离.2)增加单元测试的真实性(通过随机数据,模拟各种场景).3)开发无侵入(不需要修改既有代码,就可以拦截 A ...

  7. RPC框架实现 - 通信协议篇

    RPC(Remote Procedure Call,远程过程调用)框架是分布式服务的基石,实现RPC框架需要考虑方方面面.其对业务隐藏了底层通信过程(TCP/UDP.打包/解包.序列化/反序列化),使 ...

  8. 为什么使用 Redis及其产品定位

    摘自:http://www.infoq.com/cn/articles/tq-why-choose-redis 传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据存储 ...

  9. VC++6.0 配置CppUTest测试环境

    最近看<软件项目成功之道>,书中无数次提及到“单元测试”对于项目成败的重要性,看到同事将CppUTest用于Linux动态库测试,于是在VC++6.0环境下搭建一个基于CppUTest的单 ...

随机推荐

  1. java基础-类成员访问权限控制

    一 前言 这篇文章是很基础的一文,没多大深度,对于开发人员必然是熟练于心.本篇文章的主题是为什么java要设置类成员访问级别?其原因也很简单,就是为了面向对象的封装特性:将类成员使用不同的访问级别控制 ...

  2. Caffe源码-Blob类

    Blob类简介 Blob是caffe中的数据传递的一个基本类,网络各层的输入输出数据以及网络层中的可学习参数(learnable parameters,如卷积层的权重和偏置参数)都是Blob类型.Bl ...

  3. Vue与Django前后台分离跨域配置

    一.跨域: 简单来说:如果前端向后端请求数据,前后端的的ip和端口都是不一致的,就是不在统一域名下,就出现了CORS跨域问题. 二.后台处理跨域 在django后台环境目录下安装插件: >: p ...

  4. RBAC-权限管理设计

    1.RBAC(Role-Based Access Control)——基于角色的访问控制.简单来说每个角色有不同的权限,通过对用户赋予不同角色来赋予其对应权限. 2.RBAC0:最基本的用户角色多对多 ...

  5. 又到了抵制Notepad++的时候了?

    逛开源中国(OSCHINA),无意中发现一贴<不用Notepad++,你还有这些更好的选择> 才发现,原来 Notepad++ 的作者侯今吾前几天又在 npp 的官网上发表了一篇个人政治意 ...

  6. 阿里巴巴供应链平台事业部2020届秋招-Java工程师

    阿里巴巴供应链平台事业部,2020届秋季校园招聘开始啦!Java开发工程师虚位以待,机会难得,占坑抓紧. 入职就发师兄,一对一师兄辅导. 在这里,你将有机会接触阿里集团的所有数据库.中间件等基础设施. ...

  7. asp.net core 3.0获取web应用的根目录

    目录 1.需求 2.解决方案 1.需求 asp.net core 3.0的web项目中,在controller中,想要获取wwwroot下的imgs/banners文件夹下的所有文件: 在传统的asp ...

  8. js的动态表格的增删改查思路

    1. 首先我们要知道,动态添加,肯定不是 在页面上写死得,而是通过js调用循环放入到页面上的,我们在写动态表格的时候不要先着急写,我们第一步要做的就是构思,要把自己的逻辑先弄清楚,不然的话,前面是好写 ...

  9. 【性能测评】DSP库,MDK5的AC5,AC6,IAR和Embedded Studio的三角函数性能

    测试条件: 1.IAR8.30开最高等级速度优化. 2.MDK5.27正式版使用AC5开最高等级优化3,开启时间优化,测试C标准库和微库MicroLib两种. 3.MDK5.27正式版使用AC6开最高 ...

  10. OpenResty + ModSecurity + OWASP CRS

    本篇将介绍如何使用OpenResty和ModSecurity 来构建自己的WAF,安装过程整体与Nginx是类似的,但也有些区别,在文中会特别指出,本篇算是用openresty对前面两篇nginx和c ...