C#的参数传递大全
传统上方法的参数总是对象,“把类型作为参数传送”的需求导致泛型概念出现,“把方法作为参数传送”的想法导致委托概念出现。
对引用类型参数,无论用什么关键字修饰都是引用传递。对值类型参数,默认的传递方式是值传递(不加任何关键字修饰),ref和out关键字提供了值类型按引用进行传递的解决方案(当然引用类型也可以用ref和out修饰,但这样已经失去了意义,因为引用类型本来就是传递的引用本身而非值的拷贝)。ref和out关键字将告诉编译器,现在传递的是参数的地址而不是参数本身,这和引用类型默认的传递方式是一样的。同时,编译器不允许out和ref之间构成重载,又充分说明out和ref的区别仅是编译器角度的,他们生成的IL代码是一样的。有人或许疑问:值类型在托管堆中不会分配内存,为什么可以按地址进行传递呢?值类型虽然活在线程的堆栈中,它本身代表的就是数据本身(而区别于引用数据类型本身不代表数据而是指向一个内存引用),但是值类型也有它自己的地址,即指针,现在用ref和out修饰后,传递的就是这个指针。若要使用 ref、out参数,则方法定义和调用方法都必须显式使用 ref、out关键字。ref参数必须在调用前初始化;out参数在传递之前不需要显式初始化,在被调用方法中初始化并在调用完成后传递给调用者。ref是有进有出,out是只出不进。当需要在方法内对值类型参数进行修改并在方法外保留此修改,我们就需要用引用方式传递值类型的参数。
无论是val还是ref类型的参数,ref和out都是以引用方式传递参数。ref传递前参数必须先初始化;out传递不要求传递前参数必须先初始化,但在函数体内须给参数赋值以使参数可以传递出来。