再发几篇可以搞个懒人系列了
这个例子讲的是C#参数传递的基本概念,比较适合初学者。
参数传递方式往往是在你接触一门语言时,需要你留意的地方,c++,java,c#都有所不同。
而这玩意又是频频被用到的。如果你不清楚的话,可能你编程的时候就会留下一些bug,
可能你写到有关参数传递的时候会有些不放心,而每次又没什么大问题,所以就懒得去研究它。
那么这篇小随笔可以帮帮你 :) 最近考试没那么多时间写“大”作,就记些小随笔聊以充数,不过这篇就不放team里了,说来这个小程序重复代码好多啊;P 言归正传
首先记住一点,c#参数传递传的是值,不是引用,不过这个值有点特殊,是所传对象的地址值。
那么如果你将一个对象作为参数传递到一个方法中,你就要注意了,你对它的修改是会影响到原来的对象的。下面的例子就能说明问题。大家看第一段测试代码,你会发现para1的str被修改了。如果你知道ref,out关键字可能这时就会问,那还要它们干吗?呵呵,接着看。
我们再看第二段代码,如果你运行了一下,你就会发现str没有被修改,怎么回事?
呵呵,这就是string对象搞得鬼。我想大家在编程中可能经常传个自己的对象,有时又传个string对象。
而它们的表现却各不相同,弄的很郁闷 ;p 这就大家经常谈到的string is a immune object ,即string对象不可被修改(那个C++CLI先不考虑),在执行p.str="original be modified !!"这步操作的时候,你做的是什么呢?
首先你新建了一个string对象,它的值是"original be modified !!",然后你这个新对象的地址值赋给了para.str的地址值,注意哦,之所以说c#传值,就是指这里的para.str只是地址的值而已,所以前面那个赋值只是将0x02改成什么0xaa之类的,下次para.str取值的时候还是到原来的0x02这个地方来取。
(希望这里大家能看懂啊~~~)
那么我们要修改string的值怎么办?这时候ref就派上用场了,这个时候传的就是地址引用而不是地址值了。在这里有点类似于c++二级指针的概念。
说完了,大家有兴趣的话看看在java中如何实现交换两个字符串。你会有收获的。
另外由于c#传的是对象的地址值,而又不提供对传值const修饰符,那么除了对传递的对象做一个深拷贝,怎么才能避免所传值被修改,有什么好的意见吗?
namespace Test
{
public class Parameter
{
public string str="original";
}
public class TestParameterPass
{
public void ModifyParameter (Parameter p)
{
p.str="original be modified !!";
}
public void ModifyString(string str)
{
str="original be modified !!";
}
public void ModifyStringRef(ref string str)
{
str="original be modified !!";
}
}
public class TestMain
{
public static void Main(string []args)
{
TestParameterPass tpp=new TestParameterPass();
//第一段测试代码
Parameter para1=new Parameter();
Console.Out.WriteLine("string in parameter = {0}", para1.str);
tpp.ModifyParameter(para1); //修改成功
Console.Out.WriteLine("string in parameter = {0}", para1.str);
//第二段测试代码
Parameter para2=new Parameter();
Console.Out.WriteLine("string in parameter = {0}", para2.str);
tpp.ModifyString(para2.str); //修改失败
Console.Out.WriteLine("string in parameter = {0}", para2.str);
//第三段测试代码
Parameter para3=new Parameter();
Console.Out.WriteLine("string in parameter = {0}", para3.str);