[转帖]关于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

发布了26 篇原创文章 · 获赞 6 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/wangdonghao137/article/details/5579114