关于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");
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值