关于C#值类型,引用类型,值传递,引用传递
来源:互联网 发布:美国制造业回流 知乎 编辑:程序博客网 时间:2024/05/17 03:11
说到参数传递,必须得弄清值类型和引用类型:
(为了容易表达,我暂且命名存放在堆中的内容为堆中对象,存放在栈上的内容为栈中对象。)
值类型存放在栈中,直接访问。如果有: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为引用类型
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");
}
......{
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");
}
- 关于C#值类型,引用类型,值传递,引用传递
- 关于C#值类型,引用类型,值传递,引用传递
- [转帖]关于C#值类型,引用类型,值传递,引用传递
- 【转】关于C#值类型,引用类型,值传递,引用传递
- 关于C#的值类型和引用类型,值传递和引用传递的区别
- c#值类型与引用类型,可空类型,值传递与引用传递
- 引用类型/值类型,引用传递/值传递
- 引用类型按值传递
- C#参数传递(值类型、引用类型)
- C#中 类和结构 值类型和引用类型以及 值传递和引用传递
- 值类型引用类型的传递
- 值类型传递和引用类型传递的区别
- C#基础原理拾遗——引用类型的值传递和引用传递
- C#值传递引用类型数据的问题
- c#中形参是引用类型但依然是值传递!!
- 引用类型参数的按值传递
- 如何实现按值传递引用类型
- ref传递引用类型
- struts国际化轻松尝试
- Closings in Letters and E-Mail Messages
- 为什么用委托
- 复用:太多还是太少
- FTP传输过程详解
- 关于C#值类型,引用类型,值传递,引用传递
- Linux Kernel Hack (1)
- 认识Struts
- 关于Java栈与堆的思考
- http://blog.csdn.net/Mailbomb/category/60005.aspx?PageNumber=2
- hibernate核心接口
- 网线-水晶头的制作
- Grails is a breath of fresh air for Java developers
- 使用c#建立虚拟目录