博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#基础知识-引用类型和值类型的区别(六)
阅读量:5272 次
发布时间:2019-06-14

本文共 1841 字,大约阅读时间需要 6 分钟。

在第一篇中我们介绍了C#中基本的15种数据类型,这15种数据类型中又分为两大类,一种是值类型,一种是引用类型。值类型有sbyte、short、long、int、byte、ushort、uint、ulong、float、double、bool,引用类型有object、string、class类型,这两大类最大的区别就是在内存中存储的位置、方式不一样。(当我们打开运行一个程序的时候,实际上就会把当前程序需要执行的资源从硬盘加载到内存中,再把内存的数据送去CPU处理),现在来看一下它们是如何来进行存储的:

 

//引用类型

publicclassTestObject

{

publicintNumberA;

}

//值类型

publicstructTestValue

{

    publicintNumberB;

}

 

在程序入口处调用:

staticvoidMain(string[]args)

{

    //创建一个TestObject对象,命名obj1

TestObjectobj1 = newTestObject();

//创建一个TestValue对象,命名value1

TestValuevalue1 = newTestValue();

 

//为变量NumberA赋值

obj1.NumberA = 1;

//为变量NumberB赋值

value1.NumberB = 6;

 

//输出两个变量的值

Console.Write("obj1={0} , value1={1}",obj1.NumberA, value1.NumberB);

Console.ReadKey();

}

 

当我们实例化对象时,在内存中是这样存储的:

简单来说,当我们实例化一个对象时如果是值类型那么这对象中的数据将会和对象一起存储在内存栈中,如果是实例化一个引用类型的对象时在内存栈中就会保存这个对象在内存堆中的地址。

 

下面我们继续实例化两个同样的类时看看不同类型的类有什么区别?

staticvoidMain(string[]args)

{

    //创建一个TestObject对象,命名obj1

TestObjectobj1 = newTestObject();

//创建一个TestValue对象,命名value1

TestValuevalue1 = newTestValue();

 

//为变量NumberA赋值

obj1.NumberA = 1;

//为变量NumberB赋值

value1.NumberB = 6;

 

TestObjectobj2 = obj1;

obj2.NumberA= 111;

TestValuevalue2 = value1;

value2.NumberB= 666;

 

//输出两个变量的值

Console.Write("obj1={0} , value1={1} , obj2={2} , value2={3}",obj1.NumberA, value1.NumberB, obj2.NumberA, value2.NumberB);

Console.ReadKey();

}

到这里猜猜会输出什么值?先思考一下,再看下面的答案。

 

是的没错,结果就是:obj1=111 , value1=6 , obj2=111 , value2=666。

为什么会出现这样的结果呢,在上面代码中明明obj1.NumberA已经赋值了1 但是会被obj2改变,value1和value2却没有受到影响,原因就是值类型和引用类型的存储方式的不同,当你把一个引用类型对象赋值给另外一个引用类型的对象时便把它们都指向了同一个地址,所以改变的是同一个对象的值,下面来看看内存中的示意图:

 

当将obj1赋值给obj2时相当于指向了同一个堆中的对象(内存地址)。

 

string不可变类型

在第一篇中我们还提到了string类型是不可变的类型,例如:

string a=”AAA”;

在内存中开辟了一块空间存储字符串”AAA”

 

string a=”BBB”;

在内存中再开辟一块空间存储字符串”BBB”

 

这样如果变量a改变了值的话不会像值类型中的变量一样修改本身的值而且另外划分一块空间存储。

想要详细了解的小伙伴可以再查查相关的资料。

 

 有兴趣的可以关注一下我个人的微信公众号:

 

       Net之道

 

 

 

转载于:https://www.cnblogs.com/leonliuyifan/p/6859614.html

你可能感兴趣的文章
MySQL常用函数
查看>>
实现绘制图形的ToolBar
查看>>
C# 串口接收数据中serialPort.close()死锁
查看>>
Python3控制结构与函数
查看>>
字符串方法title()、istitle()
查看>>
yield语句
查看>>
java序列化问题
查看>>
Html.Partial和Html. RenderPartial用法
查看>>
查看linux系统中占用cpu最高的语句
查看>>
[洛谷P1738]洛谷的文件夹
查看>>
Ubuntu server 16.04的安装 以及配置(服务器版)
查看>>
Jtest 对象库的使用(Object Repository)
查看>>
phpstudy的mysql版本升级至5.7
查看>>
ubuntu server设置时区和更新时间
查看>>
《弟子规》下的沉思
查看>>
B. Beautiful Paintings
查看>>
AtCoder Beginner Contest 103
查看>>
Codeforces 589F Gourmet and Banquet
查看>>
随机字符串。
查看>>
Create参数为:nil/self/application的区别
查看>>