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)中,栈是内存中一种特殊的数据结构,也称为线性表,栈按照后进先出的原则存储数据,先进入的数据被压入栈底,最 ...
随机推荐
- flask源码解析之上下文为什么用栈
楔子 我在之前的文章<flask源码解析之上下文>中对flask上下文流程进行了详细的说明,但是在学习的过程中我一直在思考flask上下文中为什么要使用栈完成对请求上下文和应用上下文的入栈 ...
- uiautomator2 手工翻译版
原文:https://github.com/openatx/uiautomator2 1.安装 pip install --pre uiautomator2 #或者你可以直接从github源码安装 ...
- 再看javascript执行上下文、变量对象
突然看到一篇远在2010年的老文,作者以章节的形式向我们介绍了ECMA-262-3的部分内容,主要涉及到执行上下文.变量对象.作用域.this等语言细节.内容短小而精悍,文风直白而严谨,读完有酣畅淋漓 ...
- iOS-构建自己的代码块【提高编码效率-Xcode代码块】
前言 2018年3月1日 农历正月十四 星期四 不知怎么地,一大早上班就想写博客: Xcode代码块 开发中,都不想写过多代码,然后就会用这种方法,去简化代码,包括MVVM框架,它也体现出来了去简化C ...
- 解决git commit 遇到datached HEAD问题
git detached HEAD 你可以认为 HEAD(大写)是”current branch”(当下的分支).当你用git checkout切换分支的时候,HEAD 修订版本重新指向新的分支. 有 ...
- 【洛谷十月月测】 P3927 SAC E#1 - 一道中档题 Factorial
题目传送门:https://www.luogu.org/problemnew/show/P3927 题目大意:给你两个正整数n,k,求n!在k进制下末尾零的数量. 我们通过简单的数学分析,便可以发现, ...
- (转)CentOS 7 单用户模式+救援模式
原文:http://blog.51cto.com/asd9577/1931442 https://www.cnblogs.com/zhangzeyu/p/6379754.html-------Cent ...
- [C语言]类型限定词const解析
作为C90增加的一个受限类型关键字,const赋予了它修饰的变量一个新属性——不变性,如果一个变量声明中带有关键字const,则无法通过赋值.增减运算来修改该变量的值. 一.指针与const结合 co ...
- mysql修改存储过程的权限
直接上代码 grant execute on procedure 表名.存储过程名(eg: student.find) to '用户名'@'host'(eg: 'volumelicense'@'%') ...
- Maven Debug
1.在pom.xml中新增plugin <plugin> <groupId>org.mortbay.jetty</groupId> <artifact ...