C# in Depth Third Edition 学习笔记-- 值类型和引用

I. C#中值类型和引用类型

1. 类class 引用类型,结构struct值类型

2. 数组是引用类型,即使元素是值类型,int[]是引用类型

3. 枚举是值类型enum

4. 委托类型delegate是引用类型

5. 接口类型interface是引用类型,但可以由值类型实现。

II. 值的表达式:表达式“2+3”的值就是5;而对于引用类型的表达式,它的值是一个引用,而不是该引用所指代的对象,如String.Empty的值不是一个空字符串,而是对空字符串的一个引用。

III. 变量的值在它声明的位置存储,局部变量的值总是存在栈stack中,引用对象的实例总是存放在堆heap中,静态变量也是。

V. 值类型不能派生出其他类型,不需要额外的信息描述值实际是什么类型;而引用类型,每个对象的开头有一个标识对象实际类型的数据块,同时还提供一些其他信息。永远都不能改变对象的类型,执行简单的强制类型转换时,运行时获取一个引用,检查它引用的对象是否为目标类型的一个有效对象,若有效返回原始引用,否则抛出异常。

误解:

误区1:结构是轻量级的类

误区2:引用类型保存在堆上,值类型保存在栈上

引用的实例总是在堆上创建无误。但是一个类中有一个int的实例变量,那个在类的任何对象中,该变量的值总是和对象的其他数据在一起,也就是在堆上。只有局部变量(方法内部声明的变量)和方法的参数在栈上。对于C#2.0及以上,很多局部变量并无完全存放在栈中,详见后续匿名方法。

误区3:对象在C#中默认是通过引用传递的:引用类型作为方法参数传递时,默认是使用“值传递”--这个值是一个引用。

VI. 拆箱和装箱

对于引用类型的变量,它的值永远是一个引用;对于值类型的变量,它的值永远是该值类型的一个值。

int i=5;
object o=i;
int j= (int)o;

i是值类型的变量,o是引用类型的变量。将i赋值给o,发生装箱:运行时将在堆上创建一个包含值(5)的对象。o的值是该对象的一个引用,该对象的值是原始值的一个副本,改变i的值对该对象的值无影响。

拆箱:o被拆箱成int 类型的值,拆箱无误(即o的值可以转化为int),复制箱内的值给j,拆箱后j和该对象没有任何关系。

拆箱很容易看出来,有强制的类型转化。什么时候会装箱呢?装箱比较隐蔽,通常为一个值类型调用ToString,Equals或GetHashCode方法是,该类型没有覆盖这些方法时,会装箱。GetType()不能被重载,值类型调用时会装箱,所以可以是有typeof代替。另外将一个值类型赋给接口的变量时,也会装箱,如IComparable x =5;

C# in Depth Third Edition 学习笔记-- 值类型和引用,布布扣,bubuko.com

时间: 2024-10-08 22:39:58

C# in Depth Third Edition 学习笔记-- 值类型和引用的相关文章

C# in Depth Third Edition 学习笔记-- 可空类型

1. 没有值怎么办? 客户下了一份订单,有订货日期,但尚未发货,但没有发货日期,怎么表述发货日期? C#2以后使用可空类型. 2. 为什么值类型的变量不能是null? 引用类型变量,其值是一个引用,即一个非空引用值提供了访问一个对象 的途径,对于null来说,作为一个特殊值,意味着不引用任何对象.所有引用的默认值都为null,内存中表示全零. 值类型变量,其值是它本身的真实数据.null不是有效的值类型的值. 3. C#1 解决不存在可空值类型 魔值:DateTime,牺牲公元元年中的某个值Da

C# in Depth Third Edition 学习笔记-- C#2的一些特性

1. Partial class: 可以在多个源文件中写一个类.特别适合部分代码自动生成,部分代码手动添加的特性. 编译器在编译前会把所有的源文件合并到意洽.但是一个方法不能在一个文件中开始,在另一个文件中结束. C#3中独有的pratial 方法: // Generated.cs using System; partial class PartialMethodDemo { public PartialMethodDemo() { OnConstructorStart(); Console.W

C# in Depth Third Edition 学习笔记-- C#2.0: 解决C#1.0的问题 1 泛型

用泛型实现参数化类型 1. 泛型更好滴编译时检查,能消除很多装箱和拆箱 2. 泛型字典 Dictionary<TKey, TValue> 1 static Dictionary<string,int> CountWords(string text) 2 { 3 Dictionary<string,int> frequencies; 4 frequencies = new Dictionary<string,int>(); 5 6 string[] words

C#学习笔记——值类型

using System; namespace ValueType { class Program { /// <summary> /// 类似Java中的“/**”注释 /// </summary> /// <param name=" args"></param> static void Main(string[] args) { //C#有三种数据类型:值类型.引用类型和指针类型 //值类型 直接存储在栈上面 int i = 0;//

iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Type

值和引用类型 Value and Reference Types 在Swift中,有两种数据类型. 一是"值类型"(value type), 它是每一个实例都保存有各自的数据,通常定义为struct, enum或tuple. 二是"引用类型"(reference types),它是多实例共享一份数据,这种类型通常定义为class. 在本文中,我们将展示值类型和引用类型各自的优点以及如何在二者之间选择. 它们有什么区别? 最基本的区别是 "值类型"

iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Types)

值和引用类型 Value and Reference Types 在Swift中,有两种数据类型. 一是"值类型"(value type), 它是每一个实例都保存有各自的数据,通常定义为struct, enum或tuple. 二是"引用类型"(reference types),它是多实例共享一份数据,这种类型通常定义为class. 在本文中,我们将展示值类型和引用类型各自的优点以及如何在二者之间选择. 它们有什么区别? 最基本的区别是 "值类型"

Berkely DB Java Edition学习笔记

Berkely DB对于高并发.要求速度快的应用来说是个不错的选择,mysql就是用BDB实现的(mysql的后台) ,mysql快,BDB比mysql还要快N倍.BDB是一种嵌入式的.非关系数据库,它与其他的关系数据库RMDBS不同,它没有提供SQL,而是提供 了自己的访问接口.作为一种嵌入式的数据库,它是进程内模式的,也就是说它和应用程序在同一内存空间运行,所以速度要高很多,与嵌入式的数据库如 Derby.HSQLDB(都是RMDBS的)相比,它效率更高,使用方法也有很大的不同.现在BDB以

C++学习笔记31,指向引用的指针(3)

我们来看一个简单的指向引用的指针的例子. #include <iostream> using namespace std; int main(){ int x=10; int y=20; int &rtx=x; //不要写成了int& *ptrx=&rtx; //因为rtx的本质是一个int int *ptrx=&rtx; *ptrx=15; ptrx=&y; rtx=y; cin.get(); } 依次单步执行:(注意rtx值的变化和ptrx的变化)

初探swift语言的学习笔记六(ARC-自动引用计数,内存管理)

Swift使用自动引用计数(ARC)来管理应用程序的内存使用.这表示内存管理已经是Swift的一部分,在大多数情况下,你并不需要考虑内存的管理.当实例并不再被需要时,ARC会自动释放这些实例所使用的内存. 另外需要注意的: 引用计数仅仅作用于类实例上.结构和枚举是值类型,而非引用类型,所以不能被引用存储和传递. swift的ARC工作过程 每当创建一个类的实例,ARC分配一个内存块来存储这个实例的信息,包含了类型信息和实例的属性值信息. 另外当实例不再被使用时,ARC会释放实例所占用的内存,这些