8.6.3 输出参数——关键字:out
输出参数和引用参数有一定程度的类似,输出参数用于将值从方法内传递到方法外。要使用输出参数只需要将引用参数的ref关键字替换为out关键字即可,但有一点必须注意的是,只有变量才有资格作为输出参数,文本值和表达式都不可以,这点要谨记。好了,我们来看一个例子,里面有引用参数和输出参数,大家可以做个对比,然后再看看它们的运行结果有何异同。如代码清单8-12所示。
代码清单8-12 输出参数
1 using System;
2 public class MethodSample
3{
4 public static void Main()
5{
6 MethodSample ms=new MethodSample();
7 int x=5;
8 string s=“猜猜我会被改变吗?”;
9 ms.DoSomething(ref x,out s);
10 Console.WriteLine("x={0},s={1}",x,s);
11}
12
13 public void DoSomething(ref int someValue1,out string someValue2)
14{
15//Console.WriteLine(someValue1);
16//Console.WriteLine(someValue2);
17 someValue1=10;
18 someValue2=“我确实被改变了”;
19}
20}
是不是形式很相似?再看运行结果:
x=10,s=我确实被改变了
咦?这和代码清单8-10的运行结果完全一样!是不是就可以认为输出参数和引用参数除了关键字不同以外,其实就是一个东西?且慢!请读者将代码清单8-12自行录入电脑,分别将第15、16行注释去掉,运行两次,看看两次结果是否相同。亲自动手做过实验的读者就能发现,去掉第15行的注释能正常编译运行,而去掉第16行的注释则编译都无法通过,编译器发出如下错误信息:
使用了未赋值的out参数"someValue2"
这说明两个问题:
❑编译器允许在方法中的任意位置、任意时刻读取引用参数的值;
❑编译器禁止在为输出参数赋值前读取它。
这意味着输出参数的初始值基本上是没意义的,因为它在使用前要被赋为新的值。因此,想通过输出参数将值传入方法的路是行不通的。
这次,我们将代码清单8-11使用输出参数改写,来看看会是怎样的结果,它和前面按引用传递有何异同。如代码清单8-13所示。
代码清单8-13 使用输出参数示例
1 public class MethodSample
2{
3 public static void Main()
4{
5 MethodSample ms=new MethodSample();
6 Rectangle rectangle=null;
7 int myValue;
8 ms.CalculateArea(out rectangle,out myValue);
9}
10
11 public void CalculateArea(out Rectangle rect,out int value)
12{
13 Rectangle tmpRect=new Rectangle();
14 tmpRect.Length+=10;
15 tmpRect.Width+=15;
16 tmpRect.Area=tmpRect.Length*tmpRect.Width;
17 rect=tmpRect;
18 value=15;
19}
20}
21
22 public class Rectangle
23{
24 public int Length=10;
25 public int Width=15;
26 public int Area;
27}
大家仔细观察代码清单8-13和代码清单8-11,除了下划线部分不同以外,还有什么不同?结果我们将稍后揭晓,按照惯例,现在我们使用图8-11来揭示代码背后的事实。
图 8-11 使用输出参数图示
现在揭晓答案,见表8-4。