C#参数详解四(输出参数)

输出参数用于从方法体内把数据传出到调用代码,它们的行为与引用参数非常类似。

如同引用参数,输出参数有以下要求:

  1. 必须在声明和调用中都使用修饰符。输出参数的修饰符是out而不是ref
  2. 和引用参数相似,实参必须是变量,而不能是其他类型的表达式。这是有道理的,因为方法需要内存位置保存返回值。
    例如,下面的代码声明了名称为MyMethod的方法,它带有单个输出参数。
void MyMethod ( out int val )//方法声明
{........(方法体)}
...
int y = 1;//实参变量
MyMethod ( out y );//方法调用

与引用参数类似,输出参数的形参担当实参的别名。形参和实参都是同一块内存位置的名称。显然,方法内对形参的任何改变在方法执行完成之后通过实参变量都是可见的。

与引用参数不同,输出参数有以下要求:

  1. 在方法内部,输出参数在能够被读取之前必须被赋值。这意味着参数的初始值是无关的,而且没有必要在方法调用之前为实参赋值。在
  2. 方法返回之前,方法内部贯穿的任何可能路径都必须为所有输出参数进行一次赋值。

因为方法内的代码在读取输出变量之前必须对其写人,所以不可能使用输出参数把数据传入方法。事实上,如果方法中有任何执行路径试图在输出参数被方法赋值之前读取它,编译器就会产生一条错误信息。

public void Add2 ( out int outValue )
{
int var1 = outValue + 2; //错误!在方法赋值之前,无法读取输出变量
}

例如,下面的代码在此展示了方法MyMethod,但这次使用输出参数。

class Program
    {
        static void Main(string[] args)
        {
            MyClass a1 = null;
            int a2;
            MyMethod(out a1, out a2);//调用方法
            Console.WriteLine(" The result :a1 = {0} , a2 = {1}",a1,a2);
        }
        static void MyMethod(out MyClass f1,out int f2)
        {
            f1 = new MyClass();//创建一个类变量
            f1.Val = 25;//赋值类的字段
            f2 = 15;//赋值int参数
        }
    }
    class MyClass
    {
        public int Val = 20;//初始化字段为20
    }

这段代码产生如下输出:

The result :a1 = BlogTest.MyClass , a2 = 15

下图阐述了在方法执行的不同阶段中实参和形参的值:

  1. 在方法调用之前,将要被用作实参的变量a1和a2已经在栈里了。
  2. 在方法的开始,形参的名称设置为实参的别名。你可以认为变量a1和f1指向的是相同的内存位置,也可以认为a2和f2指向的是相同的内存位置。a1和a2不在作用域之内,所以不能在 MyMethod中访问。
  3. 在方法内部,代码创建了一个MyClass类型的对象并把它赋值给f1,然后赋一个值给f1的字段,也赋一个值给f2。对f1和f2的赋值都是必需的,因为它们是输出参数。
  4. 方法执行之后,形参的名称已经失效,但是引用类型的a1和值类型的a2的值都被方法内的行为改变了。

在这里插入图片描述

对于输出参数,形参就好像是实参的别名一样,但是还有一个需求,那就是它必须在方法内进行赋值


版权声明:本文为weixin_46433786原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。