[转帖]关于C#值类型,引用类型,值传递,引用传递
说到参数传递,必须得弄清值类型和引用类型:
(
为了容易表达,我暂且命
名存放在堆中的内容为堆中对象,存放在栈上的内容为栈中对象。
)
值类型存放在栈中,直接访问。如果有:
int a=0;int b=a;
就产生了两个栈中对象。
引用类型需要在堆中显
式分配,且不能直接访问,需要在栈中分配一个栈中对象(C++叫指针,C#叫引用)指向其堆中对象
。
如果:
StringBuilder
strb = new StringBuilder();
StringBuilder strb2 = strb;
则在堆中只有一个堆中
对象,只是栈中有两个栈中对象指向堆中对象。
可以看出:每个变量都是一个栈中对象。不管是值类型还是引用类型,
只是值类型的栈中对象就是其内容,而引用类型的栈中对象只是一个指向堆中对象的地址。
判断是值类型还是引用类型:
int
a1 = 10;
StringBuilder strb1 =
new
StringBuilder("ABC");
int
a2 = a1;
StringBuilder strb2 = strb1;
bool
bl1 =
object
.ReferenceEquals(a1,a2);
//false
为值类型
(
因为值类型要装箱
)
bool
bl2 =
object
.ReferenceEquals(strb1,strb2);
//true
为引用类型
参数传递分值传递和引用传递两种。
通常,在没有显式指出ref和out时都是值传递
。
值传递:传的是对象的值拷贝。
(
即函数内参数对象是调用
时传递对象的栈中对象的拷贝。
)
引用传递:传的是栈中对象的地址。
(
即函数内参数对象与调
用时传递对象完全是同一栈中对象。
)
现在用例子来说明传值跟传地址的不同:
private
void
button2_Click(
object
sender, System.EventArgs e)
{
StringBuilder strb1 =
new
StringBuilder();
StringBuilder strb2 =
new
StringBuilder();
Test1(strb1);
Test2(
ref
strb2);
string
str1 = strb1.ToString();
//str1
值
:"A"
string
str2 = strb2.ToString();
//str2
值
:"BC"
}
void
Test1(StringBuilder strb)
{
//strb
和
strb1
是两个栈中对象,但指向相同的地址,
这个操作是改变堆中对象
strb.Append("A");
//
这里将
strb
指向一个新的堆中对象,所以后面的操作与
strb1
指向的栈中对象无关
strb =
new
StringBuilder("B");
strb.Append("C");
}
void
Test2(
ref
StringBuilder strb)
{
//
这里的
strb
和
strb2
是同一个栈中对象,所以改变
strb
的值使其指向另一个对象也等于改变
strb2
strb =
new
StringBuilder("B");
strb.Append("C");
}
转自:http://www.cnblogs.com/greatandforever/archive/2008/07/08/1238180.html