黑马程序员技术交流社区

标题: 关于out与ref的传参内存原理 [打印本页]

作者: 胡志超    时间: 2013-3-24 15:22
标题: 关于out与ref的传参内存原理
本帖最后由 胡志超 于 2013-4-10 21:46 编辑

之前一直在想这个问题,只是其中又有一些地方不是很明白。
作者: 曾玉锋    时间: 2013-3-24 18:03
本帖最后由 曾玉锋 于 2013-3-24 22:03 编辑

额,没必要纠结太底层的东西哈。下面是我的对ref与out的理解
ref与out 一般是用于值类型参数传递的时候,因为对于引用类型的对象,没必要用ref与out修饰,结果都一样的(string 类型除外,因为string类型的对象的不可变性)。
下面是分析值类型的参数传递
out:相当于是有一个空间来等待接收东西,所以,是否给用out修饰的变量赋值,对其结果没有任何影响,因为编译器会始终认为传入的out修饰的变量为未赋值状态。
ref: 如果未被ref修饰,则传递的参数和方法中操作的参数其实不是同一个对象,而是从原参数对象中copy了一份值赋给一个新的对象,然后在方法中对这个新的对象进行操作,所以,对这个新对象的任何操作,不影响原参数对象。
而如果被ref修饰,则相当于把参数对象本身传入方法中,所以对参数的任何修改都会得到保留。


作者: 朱传波    时间: 2013-3-24 18:51
可以看一下我的这个帖子,里面有详细的介绍和实例
http://bbs.itheima.com/forum.php ... mp;page=1#pid256512
作者: 邓建军    时间: 2013-3-24 19:45
ref  out是用来修饰方法的参数的
调用者在给这个参数传值时候,传递的不是变量值,而是变量的地址
当有多个返回值的时候
传递的时候不能直接传匿名对象,而要传变量因为ref out是要传递变量的地址。
ref在方法中可以赋值也可以不赋值
out在方法结束之前必须赋值
ref侧重于修改out侧重于输出
ref在传递之前一定要有初始值
作者: 许正龙    时间: 2013-3-25 10:31
ref的参数必须在传递前先赋值
out的参数在函数外部可以不赋值,即便在外部赋值了,方法中也不能用。但是在方法中必须赋值。
作者: DWC_5101    时间: 2013-3-26 23:21
out只出不进,ref有出有进
作者: 黑马-杨鹏立    时间: 2013-3-27 01:25
关于out与ref的传参内存原理 ?
你想知道的应该是指堆栈问题吧。。。
这个涉及的就是值类型和引用类型这两块。。。当你明白了ref,out的使用及值类型和引用类型你所指的“内存原理”就一目了然了
ref必须先初始化,因为是引用,所以必须先“有”,才能引用,而out则是内部为外部赋值,所以不需要初始化,而且外部初始化也没用。
ref应用场景内部对外部的值进行改变,out则是内部为外部变量赋值,out一般用在函数有多个返回值的场所。

针对这个我先说说out的用法,为什么要有out。。。
我们一般在写方法的时候 有时需要返回值有时又不用,那么当我们需要返回值时通常都是访问修饰符加返回值类型加方法名例如:
public string GetName(int id){}这样能得到一个string的返回值。通常情况能满足我们的需求。
例如我们要做这样一个功能,在数据库中取出所有产品信息,在对该产品进行分页处理。这时只返回一个list集合是不够的(这里我把表中每行数据转换为一个实体model在声明泛型结合就不展开说了针对问题说吧不然跑题了)所以我们需要传出该分类的总行数
例:public list<model> GetAllModel(out int Rows)//定义一个方法返回一个泛型集合和该分类的总行数
{
//out修饰的数据要先赋值才能使用,如果out不赋值这个方法是不可能通过编译器的
具体方法就不写出来了
这里假如Rows=5;
}
int rows=0;
引出前台调用;getAllModel(out rows);
接下来你在打印出来rows的值发现rows已经改变,这里又引出引用类型,说明out为引用类型,所以他是在堆中,而值类型是在栈中。你所说的“内存原理”就是堆栈问题。
作者: ↖落葉下♀媃媚    时间: 2013-3-28 14:26
out只能传出,ref既能传入也能传出




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2