《Effective C#》:值类型和引用类型

在C#中有两种类型的数据,一种是值类型数据,一种是引用类型数据。在编 码的时候区分这两种类型数据,可以避免一些细小的编码错误。

首先说 说什么类型是值类型,例如:int、float、bool之类的基础类型,以及用struct 定义的类型,如:DateTime。除此外,如string,数组,以及用class定义的类 型等都是引用类型。对于C#来说,很难罗列出所有类型进行一一分别,这需要自己在编码过程中进行分析总结。

为了更好地说明两种类型之间的区别, 借用如下的表格来说明。

  值类型 引 用类型
内存分配地点 分配在栈中 分配在 堆中
效率 效率高,不需要地址转换 效率 低,需要进行地址转换
内存回收 使用完后,立即 回收 使用完后,不是立即回收,等待GC回收
赋值 操作 进行复制,创建一个同值新对象 只是对原有对象的引用
函数参数与返回值 是对象的复制 是原有 对象的引用,并不产生新的对象
类型扩展 不易扩 展 容易扩展,方便与类型扩展

通过如上细 致对比,大家对于值类型和引用类型有个清楚的概念。

不过,无论是对 于值类型还是引用类型来说,对于其作为函数参数或者返回值的时候,都是容易 犯错误的地方。

对于值类型来说,当其作为函数参数的时候,希望在函 数中被修改,那么直接如下操作是不能被修改的。

public void Increment( int i )
{
  i++;
}

要想在函数 中对传进去的参数做真正的修改,需要借助于ref这个关键字,那么正确的形式 如下。

public void Increment( ref int i )
{
  i++;
}

也就是说,如果需要在函数中对值类型参数进行修 改,需要用ref或者out进行标识才能真正实现。

而对于引用类型来说, 当其作为函数参数的时候,它所遇到的情况恰恰与值类型相反,即不希望在函数 中被修改,举例如下。

public void AddValue( MyType typValue )
{
  typValue.Count = typValue.Count + 15;
}

时间: 2024-09-19 09:02:57

《Effective C#》:值类型和引用类型的相关文章

.NET中的六个重要概念:栈、堆、值类型、引用类型、装箱和拆箱

内容导读 •概述 •当你声明一个变量背后发生了什么? •堆和栈 •值类型和引用类型 •哪些是值类型,哪些是引用类型? •装箱和拆箱 •装箱和拆箱的性能问题一.概述 本文会阐述六个重要的概念:堆.栈.值类型.引用类型.装箱和拆箱.本文首先会通过阐述当你定义一个变量之后系统内部发生的改变开始讲解,然后将关注点转移到存储双雄:堆和栈.之后,我们会探讨一下值类型和引用类型,并对有关于这两种类型的重要基础内容做一个讲解. 本文会通过一个简单的代码来展示在装箱和拆箱过程中所带来的性能上的影响,请各位仔细阅读

值类型与引用类型(中)

本文将介绍以下内容: 类型的基本概念  值类型深入 引用类型深入 值类型与引用类型的比较及应用    1. 引言 上回[第八回:品味类型---值类型与引用类型(上)-内存有理]的发布,受到大家的不少关注,我们从内存的角度了解了值类型和引用类型的所以然,留下的任务当然是如何应用类型的不同特点在系统设计.性能优化等方面发挥其作用.因此,本回是对上回有力的补充,同时应朋友的希望,我们尽力从内存调试的角度来着眼一些设计的分析,这样就有助于对这一主题进行透彻和全面的理解,当然这也是下一回的重点. 从内存角

C#高级编程阅读笔记一(关于值类型和引用类型)

笔记|编程|高级 数据在内存中的存储位置,取决于它的数据类型,在C#中,分为值类型和引用类型,值类型的数据存储在内存中的堆栈中,每个变量或程序都有自己的堆栈,不可以共用一个堆栈地址.当数据一个值类型的变量传递到另一个相同类型的变量时,会在堆栈中分配两个不同的地址. 而引用类型的数据存储在内存中的堆中,可以不同的变量或程序共同使用同一个位置的数据.当数据从一个引用类型的变量传递到另一个相同类型的变量时,只是把这个变量的引用地址传递给新的变量,同时引用当前堆中存储的数据. 可以通过实例得到详细结论:

C#基础(四)(C#预定义值类型和引用类型)

一.预定义类型. 1.值类型和引用类型 C#中的数据类型,可以分为值类型和引用类型,值类型存储在堆栈上,而引用类型存储在托管堆上. 如下代码示例, int i=10; int j=i; i和j的值都是10,并且在内存中会有两个地方存储10. 再看下面的代码 Vector x=new Vector(); x.Value=20; Vector y=x; Console.WriteLine(y.Value); y.Value=50; Console.WriteLine(x.Value); Vector

C#类和接口、虚方法和抽象方法及值类型和引用类型的区别

1.C#类和接口的区别 接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念! 而类是负责功能的具体实现! 在类中也有抽象类的定义,抽象类与接口的区别在于: 抽象类是一个不完全的类,类里面有抽象的方法,属性,也可以有具体的方法和属性,需要进一步的专业化. 但接口是一个行为的规范,里面的所有东西都是抽象的! 一个类只可以继承一个基类也就是父类,但可以实现多个接口 PS:接口除了规范一个行为之外,在具体项目中的实际作用也是十分重要的,在面向对象的设计原则以及设计模式的使用中,无不体现

浅析值类型与引用类型的内存分配

大家都知道要学好 .NET,深入了解值类型和引用类型是必不可少的.在这里我给大家简单分析一下它们内存分配的区别和联系. 在分析之前,我们先行构造出一个最简单的类引用类型: public class MyClass { } 局部变量的声明 在我们使用类型时,代码里面必然少不了变量的声明,我们先看一下方法内的局部变量的声明,请看如下代码: private static void Main() { int i; MyClass mc; i = 5; mc = new MyClass(); } 当一个局

C++:从栈和堆来理解C#中的值类型和引用类型

C++中并没有值类型和引用类型之说,标准变量或者自定义对象的存取默认是没有区别的.但如果深入地来看,就要了解C++中,管理数据的两大内存区域:栈和堆. 栈(stack)是类似于一个先进后出的抽屉.它的体积是有限的,一般为2M左右. 而堆(heap)则相对来说体积可以很大,这一般跟计算机的虚拟内存设置有关系. 栈中存取对象的内存是自动回收的,用完即销毁了,一般方法内部的变量和参数都是通过栈来存取的(但也正因为如此,它们的生命周期很短).但它的问题是,体积有限. 一些大的对象,我们可能要通过堆来创建

Emit学习-答疑篇-值类型和引用类型在使用时的区别

今天下午兴冲冲的写完一段IL代码,用Reflector转成C#代码看了下,没有问 题,于是引用持久化到硬盘上的动态程序集,想要试一下其中的方法,但是运行 后却出现了System.AccessViolationException,提示信息为:"尝试读取或写入 受保护的内存.这通常指示其他内存已损坏.".看着错误提示一阵头大,新配 的电脑内存损坏是不太可能了,只好从自己的程序中找原因. 经过一阵调试,终于找到了引发异常的地方,是在构造函数中用 DateTime.Now.Millisecon

[你必须知道的.NET]第十回:品味类型---值类型与引用类型(下)-应用征途

本文将介绍以下内容: 类型的基本概念 值类型深入 引用类型深入 值类型与引用类型的比较及应用 1.引言 值类型与引用类型的话题经过了两个回合([第八回:品味类型---值类型与引用类型(上)-内存有理]和[第九回:品味类型---值类型与引用类型(中)-规则无边])的讨论和切磋,我们就基本的理解层面来说已经差不多了,但是对这一部分的进一步把握和更深刻的理解还要继续和深化,因为我自己就在两篇发布之际,我就得到装配脑袋兄的不倦指导,之后又查阅了很多的资料发现类型在.NET或者说语言基础中何其重要的内涵和