目录
1、值类型与引用类型
1.1 值类型
1.2 引用类型
2、值类型存储方式
3、引用类型的值的存储方式
3.1 引用类型在复制时,传递的是对象的引用
3.2 字符串的不可变性
1、值类型与引用类型
1.1值类型:int ,double,char,decimal,bool,enum,struct
1.2引用类型:string,数组,自定义类,集合,object,接口
2、值类型的存储方式
2.1值类型在复制时,传递的是这个值的本身。如:
int n1 = 10;
int n2 = n1;
n2 = 20;
Console.Write(n1);
Console.Write(n2);
Console.ReadKey();
输出的值是 10 , 20
在int n1 =10;int n2 = n1 时,在栈上开辟了两块空间n1,n2,且两块空间内存的都是10;在n2 = 20时,n2的值被重新赋值为20。
3、引用类型的值的存储方式
3.1引用类型在复制时,传递的是对象的引用。
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "张三";
Person p2 = p1;
p2.Name = "狂徒";
Console.WriteLine(p1.Name);
Console.WriteLine(p2.Name);
Console.ReadKey();
}
public class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
输出的结果是 狂徒 , 狂徒
为什么会是这样的呢?这是因为引用类型在复制时,传递的是对象的引用。
在person p1 = new person()时,在栈和堆上都开辟了一块空间,堆中存的是p1的对象new person();而栈中存的是p1在堆中的存储空间的地址。在person p2 = p1的时传递的是对象的引用,并在栈上存入该对象引用的地址。思考为什么p2会与p1指向同一个堆空间对象上?那是因为在 person p2 ;时没有是使用关键字new,直接复制了person p1的对象nwe person()。换句话说就是person p2没有开辟空间,直接复制了对象的引用。(对象存在堆中)
参考:使用关键字new,new 会做三件事:一在堆中开辟一块空间,二在空间中创建对象,三调用对象的构造函数。
当 p2 = "狂徒" 时
(看红色字迹)
当 p2.name = "狂徒" 后,p2的堆中的对象就被复制成了 "狂徒",但是 p1与p2又指向的是同一块堆空间,所以p1的对象引用也会被复制成 "狂徒"。
3.2、字符串的不可变性
string s1 = "张三";
string s2 = s1;
s2 = "狂徒";
Console.WriteLine(s1 );
Console.WriteLine(s2);
Console.ReadKey();
输出的结果是 张三 ,狂徒
同样是引用类型,为什么 string类型会不一样呢?这是因为 string类型具有不可变性。让我们来看看它内部的工作原理吧。
在声明 string 类型时,每次声明都会在堆中开辟一块新的空间,即栈 s1,s2中存放的堆地址是不一样的。当给 s1,s2中任一个赋值时,另一个的值不会被改变。这就是string类型的不可变性。
本文到这里就结束了,若有错误或是需要补充的地方,欢迎在评论区留言改正和补充。