C# 值类型 引用类型
CLR 定义了两种类型,ReferenceTypes引用类型 和 ValueTypes 值类型。我们定义的各种Class都是引用类型,而我们用的decimal int 之类是值类型。
他们有什么区别呢?为什么 CLR要搞出两种类型出来呢?肯定是因为他们各有各的优点。我们会分别论述
首先 引用类型,我们知道 创建引用类型的实例 必须通过new 这个关键字,比如 说 Person p=new Person();
这个时候 会在托管堆中申请出一片空间出来,用来存放我们真正的这个对象,同时在栈中 会存放一个引用p 存放该对象在堆中的内存地址。也就是说 p中存放的是地址,我们管p叫做对对象的引用。
也就是说 我们没创建一个引用类型的对象,都要通过new来申请空间,但是在堆中申请空间 比较慢而且损耗性能。所以CLR有了值类型的想法,值类型 就是把所有数据都存放在栈里面,因为栈比较快,所以性能会比较好。
比如 int num=3; 就在栈 内存中 有个变量num 它里面存的就不是什么内存地址 ,而是真正的数值3。
你可能会说,既然栈快,那我们干脆都放在栈里好了。这也是行不通的。我们写程序的时候会经常有赋值操作,比如
我们写 Person p2=p; 也就是说我们 又定义了一个p2对象 ,指向原先的p对象。这个时候在内存中真正发生了呢,堆中并没有创建一个新的对象,而是 有个新的p2引用指向原来的对象而已。p 和p2指向的是同一个对象。
而 对于 int num=3; int num2=num;而言 就要在栈中完整复制一个空间。这样的话,如果本身对象体积比较大,经常复制的话,空间需要就太大了。而同样对于引用类型,只不过是复制了内存地址而已。
所以 这两种类型都是有其存在意义的。当然,上面说的这些并不代表只有这么多优点。
我们知道C#中所有对象 都继承自 system.object。这一点不要有半点怀疑。那什么时候 分支出了值类型和引用类型两种呢?
system.object有个抽象子类system.ValueType, 具体的struct Enum等都是继承自这个抽象类,但是这些具体的值类型之后 却是不可以再“遗传”的,不可以再有子类,
就从这里 断了根。 而引用类型则是从System.object直接往下继承,(不经过system.ValueType),类可以有自己的子类,一直向下,绵延不绝。
关于引用类型 和值类型的赋值。看下面的示例
class 引用类型和值类型
{
public static void Main(string[] args)
{
PersonClass p1 = new PersonClass();
p1.name = "shenwei"; p1.age = ; p1.mobile = "xxxxx";
PersonStruct p2 = new PersonStruct();
Console.WriteLine(p2.age);
p2.name = "zhangxiaomao"; p2.age = ; p2.mobile = "yyyyy"; //重新定义两个对象
PersonClass p3 = p1; //指向p1
PersonStruct p4 = p2; //复制P2 //当我们对 新的对象做修改时,原来的对象会改变吗?
p3.name = "changed";
p4.name = "changed"; Console.WriteLine(p1.name);
Console.WriteLine(p2.name); Console.ReadKey();
}
} public class PersonClass
{
public int age;
public string name;
public string mobile;
}
public struct PersonStruct
{
public int age;
public string name;
public string mobile;
}
运行结果
那么当我们要定义自己的类型时,如何决定我们是定义成 引用类型 class 呢,还是定义成值类型 呢
有这么几条原则
如果要定义成值类型,那 你的类型 一定不可以 继承其他类型,也不可以被其他类型继承,这是必须要遵守的,上面也讲过 值类型 断了根
还有就是 我们很少需要对 结构体中的字段进行修改。甚至 我们写代码的时候 习惯直接设置 结构体中的字段为readonly形式的,即只读的。
我个人认为 结构体就是为了 更方便的使用 一整块基本不变的数据而已。
那除了列的这种情况,基本都是定义成class了。
C# 值类型 引用类型的更多相关文章
- 30天C#基础巩固-----值类型/引用类型,泛型,空合并操作符(??),匿名方法
一:值类型/引用类型的区别 值类型主要包括简单类型,枚举类型,和结构体类型等,值类型的实例通常被分配在线程堆栈上面变量保存的内容是实例数据本身.引用类型被分配在托管堆上,变量保存的是地址.引 ...
- 数往知来C#之接口 值类型与引用类型 静态非静态 异常处理 GC垃圾回收 值类型引用类型内存分配<四>
C# 基础接口篇 一.多态复习 使用个new来实现,使用virtual与override -->new隐藏父类方法 根据当前类型,电泳对应的方法(成员) -->override ...
- 深入C#内存管理来分析值类型&引用类型,装箱&拆箱,堆栈几个概念组合之间的区别
C#初学者经常被问的几道辨析题,值类型与引用类型,装箱与拆箱,堆栈,这几个概念组合之间区别,看完此篇应该可以解惑. 俗话说,用思想编程的是文艺程序猿,用经验编程的是普通程序猿,用复制粘贴编程的是2B程 ...
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...
- C# 语法二 值类型引用类型
1.值类型 2.引用类型 一 值类型 值类型存放在栈中,引用类型存放在堆中. 值类型有:数值.布尔.字符,例如:int i;bool i2;char cr='a'; 二 引用类型 大多数类型是引用类型 ...
- [No0000136]6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...
- JavaScript:值类型 引用类型
JavaScript类型 (1)值类型:数值.布尔值.null.undefined. (2)引用类型:对象.数组.函数. 1.string var str="hongda"; v ...
- (值类型引用类型)和null的关系
1.null null表示变量没有指向任何对象. 2.值类型 包括 bool.结构体.枚举.int.double.float等等 .在.NET中值类型都继承自ValueType. 3. 引 ...
- JAVASCRIPT数据类型(值类型-引用类型-类型总览)
值类型:也称为原始数据或原始值(primitive value). 这类值存储在栈(stack)中,栈是内存中一种特殊的数据结构,也称为线性表,栈按照后进先出的原则存储数据,先进入的数据被压入栈底,最 ...
随机推荐
- 768. Max Chunks To Make Sorted II
This question is the same as "Max Chunks to Make Sorted" except the integers of the given ...
- flask源码解析之上下文为什么用栈
楔子 我在之前的文章<flask源码解析之上下文>中对flask上下文流程进行了详细的说明,但是在学习的过程中我一直在思考flask上下文中为什么要使用栈完成对请求上下文和应用上下文的入栈 ...
- webpack快速入门——实战技巧:开发和生产并行设置
package.json中,devDependencies和dependencies是不同的 devDependencies:开发依赖 dependencies:生产依赖(线上) 1.安装生产环境的依 ...
- webpack快速入门——实战技巧:webpack优化黑技能
1.抽离jquery,vue(多个第三方类库抽离) 修改入口文件(webpack.config.js中) entry: { entry: './src/entry.js', jquery:'jquer ...
- CPU 分支预测
去年在安宁庄的时候, 有个同事阐述了一个观点:php中的if else 在执行时考虑到效率的原因,不会按我们的代码的顺序一条一条去试,而是随机找出一个分支,执行,如果不对,再随机找到一个分支 当时由 ...
- (转)AIX rootvg 镜像创建与磁盘更换
# prtconf | grep disk # chdev -l hdisk1 -a pv=yes # extendvg rootvg hdisk1 # chvg -Qn rootvg # lsvg ...
- EF基础知识小记一
1.EF等ORM解决方案出现的原因 因为软件开发中分析和解决问题的方法已经接近成熟,然后关系型数据库却没有,很多年来,数据依然是保存在表行列这样的模式里,所以,在面相对象和高度标准化的数据库中产生了一 ...
- 安卓的SlidingMenu配置
最近用到了界面的优化,使用SlidingMenu开源库比较方便,为了方便学习,我整理了一下配置过程. 1.准备资料. 首先下载这两个ActionBarSherlock和SlidingMenu,如图:
- CentOS6.5安装php7+nginx+mysql实现安装WordPress
安装php7+nginx参考该博客http://blog.csdn.net/whatday/article/details/50645117 安装php7参考http://blog.csdn.net/ ...
- linux svn 开机启动
在/etc/init.d中建立svnboot,内容如下: #!/bin/bash if [ ! -f "/usr/bin/svnserve" ] then echo "s ...