c# 值类型和引用类型,值传递和引用传递
值类型和引用类型
在c#内置基本类型当中,除了object和string外,都是引用类型。同时,自己定义的类,也都是引用类型。因为自定义类全部继承自System.Object。
更多参见:.net中6个重要的基础概念:Stack, heap, Value types, reference types, boxing and Unboxing.
值传递和引用传递
创建控制台程序文件:ValueAndReference.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CSType
{
public class ValueAndReference
{
public ValueAndReference()
{
TestClass tc = new TestClass();
ChangeValue(tc.ps);//值传递
Console.WriteLine("tc.ps value:" + tc.ps);
//output : 绯红女郎,哎呀哎呀!
ChangeValue( ref tc.ps);//使用ref关键来强制为引用传递
Console.WriteLine("ref tc.ps value:" + tc.ps);
//output : 绯红女郎,哎呀哎呀! was Changed
ChangeObject(tc);//类默认为引用传递
Console.WriteLine(" tc.ps value:" + tc.ps);
//output: Hello world
string s = "海盗船长,嘿咻嘿咻";
ChangeValue(s);//值传递
Console.WriteLine("s value:" + s);
//output: 海盗船长,嘿咻嘿咻
ChangeValue(ref s);//使用ref关键来强制为引用传递
Console.WriteLine("s value:" + s);
//output: 海盗船长,嘿咻嘿咻 was Changed
Console.ReadLine();
}
public void ChangeValue( string s)
{
s = s + " was Changed";
}
public void ChangeValue(ref string s)
{
s = s + " was Changed";
}
public void ChangeObject(TestClass o)
{
o.ps = "Hello world";
}
}
public class TestClass
{
public string ps = "绯红女郎,哎呀哎呀!";
public TestClass()
{
}
}
}
我们来分析一下:
1.类TestClass是辅助类,是辅助我们测试的
2.类ValueAndReference里面有3个方法,两个:ChangeValue和一个ChangeObject,方法名字无所谓,你可以写个ChangeObject123,ChangeObjectsdfsdf来用。
3.C#里面的值类型变量进行传递时,全部是值传递。
c#里面的引用类型变量进行传递时,全部是引用传递。但是string例外。比如:
string s = "海盗船长,嘿咻嘿咻";
ChangeValue(s);//值传递
Console.WriteLine("s value:" + s);
//output: 海盗船长,嘿咻嘿咻
这里的变量s本来是引用类型,但是传递时是作为值传递。
4. 值传递:
string s = "海盗船长,嘿咻嘿咻";
ChangeValue(s);//值传递
Console.WriteLine("s value:" + s);
//output: 海盗船长,嘿咻嘿咻
s变量的作用域不在ChangeValue方法内部。我们使用参数的方式把s传递进去,注意这里传递的是s变量的值。不是s变量在内存里面的地址。等于把s变量copy了一份传递给ChangeValue.虽然,s变量的值在ChangeValue内部被改变了,但是ChangeValue(s)无法改变外部s变量的值。
5.引用传递:
ChangeValue(ref s);//使用ref关键来强制为引用传递
Console.WriteLine("s value:" + s);
这个时候,就是把s变量在内存里面的地址传递过去了,不是值的copy.因此,我们当我们把这个内存地址所指向的值修改后,外部的s变量的值也就被修改了。因为方法内外的s变量是一个内存地址,指向同一个值。
===========================
通俗例子:
假如我有100¥(外部s变量),现在我给你100¥(传递s变量),但是我不是直接给你,而是把我手里的100复制一下,然后给你100(传递的方式:值传递),你去买东西后,还剩40(ChangeValue(string s)函数的功能),但是我的100还是没变(外部s变量的值没变化)。
再来,我有100¥,在钱包里放着(外部s变量)。我把放钱包的地方告诉你,你直接去钱包里面拿100¥(传递方式:引用传递,就是传内存地址),你去买东西后,还剩40,然后你把剩余的钱放回钱包(ChangeValue(ref string s)函数的功能),我的钱也只有40¥了(外部s变量的值被改变了)