本章内容:
方法的结构
方法体内部的代码执行
局部变量
局部常量
控制流
方法调用
返回值
返回语句和void方法
局部函数
参数
值参数
引用参数
引用类型作为值参数和引用参数
输出参数
参数数组
参数类型总结
方法重载
命名参数
可选参数
栈帧
递归
引用类型作为值参数顸引用参数
在前几节中我们看到了,对于一个引用类型对象,不管是将其作为值参数传递还是作为引用
参数传递,都可以在方法成员内部修改它的成员。不过,我们并没有在方法内部设置形参本身。
本节来看看在方法内设置引用类型形参时会发生什么。
将引用类型对象作为值参数传递如果在方法内创建一个新对象并赋值给形参,将切断
形参与实参之间的关联,并且在方法调用结束后,新对象也将不复存在。
将引用类型对象作为引用参数传递如果在方法内创建一个新对象并赋值给形参,在方
法结束后该对象依然存在,并且是实参所引用的值。
下面的代码展示了第一种情况----将引用类型对象作为值参数传递:
class MyClass
{public int Val=20;
}class Program
{static void RefAsParameter(MyClass f1){f1.Val=50;Console.WriteLine($"After member assignment:{f1.Val}");f1=new MyClass();Console.WriteLine($"After new object creation:{f1.Val}");}static void Main(){MyClass a1=new MyClass();Console.WriteLine($"Before method call: {a1.Val}");RefAsParameter(a1);Console.WriteLine($"After method call:{a1.Val}");}
}
图6-9阐明了关于上述代码的以下几点
在方法开始时,实参和形参指向堆中相同的对象。
在为对象的成员赋值之后,它们仍指向堆中相同的对象。
当方法分配新的对象并赋值给形参时,(方法外部的)实参仍指向原始对象,而形参指向
的是新对象。
在方法调用之后,实参指向原始对象,形参和新对象都会消失。
下面的代码演示了将引用类型对象作为引用参数的情况。除了方法声明和方法调用时要使用
ref关键字外,与上面的代码完全相同。
class MyClass
{public int Val=20;
}class Program
{static void RefAsParameter(ref MyClass f1){//设置对象成员f1.Val=50;ConSole.WriteLine($"After member assignment:{f1.Val}");//创建新对象并赋值给形参f1=new MyClass();ConSole.WriteLine($"After new object creation:{f1.Val}");}
}static void Main(string[] args)
{MyClass a1=new MyClass();Console.WriteLine($"Before method call:{a1.Val}");RefAsParameter(ref a1);Console.WriteLine($"After method call:{a1.Val}");
}
你肯定还记得,引用参数充当形参的别名。这样一来上面的代码就很好解释了。图6-10阐
明了上述代码的以下几点。
在方法调用时,形参和实参指向堆中相同的对象。
对成员值的修改会同时影响到形参和实参。
当方法创建新的对象并赋值给形参时,形参和实参的引用都指向该新对象。
在方法结束后,实参指向在方法内创建的新对象。