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)中,栈是内存中一种特殊的数据结构,也称为线性表,栈按照后进先出的原则存储数据,先进入的数据被压入栈底,最 ...
随机推荐
- jzoj5710
對於每個詢問,我們先考慮插入1~r中每個數的答案,這樣子就不用考慮後面數對現在的影響 那麼我們可以在權值線段樹的每一個位置存儲每一個值最後一次結束的位置 問題變成了,如何判斷區間連續? 我們可以對線段 ...
- hdoj1175 连连看(dfs+剪枝)
处理连连看问题. 要求拐弯方向不多于两次.剪枝很重要!!! 用dir记录当前方向.Orz,居然没想到. #include<iostream> #include<cstring> ...
- 浅谈对MVC的认识
MVC是model(模型),view(视图),Controller(控制)的缩写. 模型层负责提供数据,和数据库相关的操作都交给模型层处理: 视图层提供交互的界面,其输出数据: 控制层负责接收各种请求 ...
- 二,windows下安装memcached服务
window下安装memcached服务的流程如下: 1. 下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached 2. 在终端(也即cmd命令界面)下输入 ‘c ...
- centos 6 下,zephir的安装和使用
centos 6 下,zephir的安装和使用 zephir或许会开启一个新的PHP编写方式. 在这之前,如果我们要编写php的扩展,一般都是c++/clang/vc等等. 但是现在,我们有了新的选择 ...
- WEB-INFO 目录
WEB-INF下面的内容都是只能由服务器级别才能访问,客户端并不能访问. 转发就是服务器级别,浏览器的地址不会变,因为,客户端发送一个请求,服务器受理之后,发现要请求内容还要再去别的请求,那么转发就是 ...
- 批处理 安装、卸载 window service
注意:安装中调用了卸载的bat,安装之前先卸载...PS:可以删除 安装代码: @echo off set filename=LXServer.exe set servicename=Service1 ...
- Java模拟双色球彩票
package practice1; import java.util.Random; import java.util.Scanner; public class Test3 { /** * * 模 ...
- python的字符串内建函数(方法)
原本总结一下,后来发现这个里面讲的很全,可以点进去参考:http://www.runoob.com/python/python-strings.html
- tensorflow基础篇-1
1.使用占位符和变量 import tensorflow as tf import numpy as np #-----创建变量并初始化----------- def first(): my_var= ...