《C#从现象到本质》读书笔记第二篇

第2章 C#类型基础(上)

类型指的是集合{类,结构,接口,枚举,委托}中的任意一个成员。任何拥有某类型的值(value)称为某类型的一个实例(instance)。

类型可以被分为值类型(结构,枚举,整型,布尔型,datetime)以及引用类型(类、接口、指针、字符串、委托、数组)。

C#支持6种类型访问修饰符。访问范围大小排序为:

1)public:没有限制。

2)protected internal:只能在所在程序集、定义的类型或派生类型进行访问。

3)internal:只能在所在程序集访问。

4)private protected:c#7.2新增的访问修饰符,等同于5和6中满足任意一个。

5)protected:只能由定义的类型或派生类型进行访问。

6)private:只能由定义的类型进行访问。

除了public和internal,其他4种修饰符不能作用于非嵌套类。

如果没有指定访问修饰符,类型的访问修饰符默认为internal,类型成员则默认为private(都是限制最大的那个)。

堆基于进程,属于进程内存空间的一部分;栈基于线程。

引用类型对象包括方法表指针和同步块索引(值类型则没有这两样东西),方法表指针指向该引用类型自己的类型对象。引用类型默认值为null。

引用类型的赋值分为深复制和浅复制。默认的情况为浅复制,浅复制只会复制地址本身,然后将这个地址赋值给新的变量,所以,新的对象和旧的对象同事指向堆上的旧对象。更改任何一个对象成员的值都会影响另一个。

深复制复制一个对象时,不仅仅把对象的引用进行赋值,还把该对象引用的值一起复制。值类型就是典型的例子。

值类型的内存分配:

1)值类型作为局部变量:普通的值类型总是分配在栈上。

2)值类型作为引用类型的成员:如果值类型为引用类型的成员,则遵从引用类型的内存分配(托管堆)和复制方式(浅复制)。

3)值类型中包含引用类型:如果一个结构体中包含了引用类型(例如结构体),则它引用类型的那部分会遵从引用类型创建的内存分配,值类型的那部分则遵从值类型创建的内存分配。

设置值类型的目的是提高程序的性能。值类型一定是密封的,不支持继承。

适用使用结构体的情况:

1)当对象的所有属性都需要在创建之初即赋值时。

2)当对象的全部属性都是值类型时。

3)当对象不需要被继承时。

值类型和引用类型在内存中的分配区别是决定其应用不同的根本原因。

按值传递的实质是传递值,不同的是这个值在值类型和引用类型的表现是不同的:

参数为值类型时,“值”为实例本身,因此传递的是实例拷贝,不会对原来的实例产生影响;

参数为引用类型时,“值”为对象引用,因此传递的是引用地址拷贝,会改变原来对象的引用指向。

值类型和引用类型的区别与联系:

它们的区别主要有:

1)所有值类型隐式派生自system.valuetype。该类确保值类型所有的成员全部分配在栈上。有三个例外:

  a)结构体如果含有引用类型成员,则该成员也会牵扯到堆的分配。

  b)静态类型,如果一个变量是静态的,则无论它是什么类型,都会分配在加载堆上。

  c)局部变量被捕获升级为密封类。

2)引用类型的初值为null,值类型则是0.

3)引用类型,栈中会有一个变量名和变量类型,指向堆中对象实例的地址。值类型仅有栈中的变量名和类型,不包括指向实例的指针。

4)值类型不能被继承,引用类型可以。

5)值类型的生命周期是其定义域。当值类型离开其定义域后将被立即销毁。引用类型则会进入垃圾回收分代算法。

6)值类型的构造函数必须为所有成员赋值。

7)可以重写引用类型的析构函数。值类型不需要析构函数。析构函数只会被垃圾回收器调用。

8)值类型没有同步块索引,不能作为线程同步工具。

它们的联系主要有:

1)值类型和引用类型可以通过装箱和拆箱互相转化。

2)所有值类型都派生自system.valuetype,它是system.object的子类。

3)类和结构体都可以实现接口。

装箱需要比原数据更多的空间,因为它需要两个引用类型的标准配置:类型对象指针和同步块索引。

装箱就是把值类型转换为object类型或由此值类型实现的任何接口类型。

拆箱的目的是为了将值拷贝到一个值类型中,所以拆箱之后,往往伴随着一次值的复制动作。

《C#从现象到本质》读书笔记(二)第2章 C#类型基础(上)的更多相关文章

  1. 《深入理解bootstrap》读书笔记:第4章 CSS组件(上)

    bootstrap三大核心之二. 包括glyphicon图标,下拉菜单(dropdown),按钮组(button group)....等等. 一. 图标字体 bootstrap3提供了200多个免费图 ...

  2. 《深入理解java虚拟机》读书笔记二——第三章

    第三章 垃圾收集器与内存分配策略 1.判断对象是否已死 引用计数法: 给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1,每当引用失效时,计数器值就减1. 任何时刻计数器为0的对象就是不 ...

  3. C#图解教程读书笔记(第4章 类:基础)

    类成员包括数据成员和函数成员. 和C/C++不同,C#在类型的外部不能声明全局变量,所有的字段都属于类型,而且必须在类型声明内部声明. 和C/C++不同,方法没有返回默认类型,所有方法必须包含返回类型 ...

  4. 《C#从现象到本质》读书笔记(三)第3章C#类型基础(下)

    <C#从现象到本质>读书笔记第3章C#类型基础(下) 常量以关键字const修饰.C#支持静态字段(类型字段)和实例字段. 无参属性的get方法不支持参数,而有参属性的get方法支持传入一 ...

  5. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

  6. SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)

    SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...

  7. 《Android开发艺术探索》读书笔记 (3) 第3章 View的事件体系

    本节和<Android群英传>中的第五章Scroll分析有关系,建议先阅读该章的总结 第3章 View的事件体系 3.1 View基本知识 (1)view的层次结构:ViewGroup也是 ...

  8. C#学习笔记——面向对象、面向组件以及类型基础

    C#学习笔记——面向对象.面向组件以及类型基础 目录 一 面向对象与面向组件 二 基元类型与 new 操作 三 值类型与引用类型 四 类型转换 五 相等性与同一性 六 对象哈希码 一 面向对象与面向组 ...

  9. 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...

随机推荐

  1. 【scrapy】其他问题2

    今天爬取豆瓣电影的是时候,出现了两个问题: 1.数据无法爬取并输出Retrying <GET https://movie.douban.com/robots.txt> 看起来像是被拦截了. ...

  2. 无法连接mysql,请检查mysql是否已启动及用户密码是否设置正确

    安装好后,登录后台提示 无法连接mysql,请检查mysql是否已启动及用户密码是否设置正确 检查mysql是否启动netstat -lnpt是否有3306端口? 一 有A 检查/www/wdlinu ...

  3. python写机器人玩僵尸骰子

    python写机器人玩僵尸骰子由Al Sweigart用python发布注意:我正在为我的僵尸骰子模拟器寻找反馈,以及这一套指令.如果你觉得有什么地方可以改进,请发邮件到al@inventwithpy ...

  4. Centos 7 下 Corosync + Pacemaker + psc + HA-proxy 实现业务高可用

    一.介绍: 1.本博客Corosync + Pacemaker + psc + HA-proxy 实现业务高可用,以httpd 服务实现高可用为例. 2.架构思路 a.三台web 节点,功能:全部安装 ...

  5. UVM1

    1.UVM: p_sequencer 的使用 http://blog.csdn.net/tingtang13/article/details/46546395

  6. jQuery之禁止Get请求缓存

    如果两次Get请求的URL完全一样,则IE浏览器会调用上次缓存的结果,不会发起新的Http请求. 解决办法:在URL最后面加上时间戳. jQuery全局设置禁止缓存 $.ajaxSetup({ cac ...

  7. f5基本介绍

    1.信息查看 1)登录: https://10.160.100.10 f5有2台,做HA IP地址分别为10.160.100.3和10.160.100.2 10.160.100.10为虚拟地址 2)基 ...

  8. Compile、Make和Build的区别

    针对Java的开发工具,一般都有Compile.Make和Build三个菜单项,完成的功能的都差不多,但是又有区别.   编译,是将源代码转换为可执行代码的过程.编译需要指定源文件和编译输出的文件路径 ...

  9. C++ 中 int 与string相互转换

    int -->  string 1.使用itoa()函数 将任意类型的数字变量转换为字串子变量. #include<stdio.h> #include<iostream> ...

  10. Java_8排序(冒泡排序和选择排序)

    1.选择排序 package demo1; public class Demo1 { public static void main(String[] args) { int[] arr= {23,5 ...