ref 和out 传值异同

ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。例如:

class RefExample

{

    static void Method(ref int i)

    {

        i = 44;

    }

    static void Main()

    {

        int val = 0;

        Method(ref val);

        // val is now 44

    }

}

传递到 ref 参数的参数必须最先初始化。这与 out 不同,out 的参数在传递之前不需要显式初始化。

示例


按引用传递值类型(如上所示)是有用的,但是 ref 对于传递引用类型也是很有用的。这允许被调用的方法修改该引用所引用的对象,因为引用本身是按引用来传递的。下面的示例显示出当引用类型作为 ref 参数传递时,可以更改对象本身。

 

class RefRefExample

{

    static void Method(ref string s)

    {

        s = "changed";

    }

    static void Main()

    {

        string str = "original";

        Method(ref str);

        // str is now "changed"

    }

}

out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。例如:

class OutExample

{

    static void Method(out int i)

    {

        i = 44;

    }

    static void Main()

    {

        int value;

        Method(out value);

        // value is now 44

    }

}

尽管作为 out 参数传递的变量不需要在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。

refout 关键字在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的,因此将不会编译以下代码:

 

class CS0663_Example

{

    // compiler error CS0663: "cannot define overloaded

    // methods that differ only on ref and out"

    public void SampleMethod(out int i) {  }

    public void SampleMethod(ref int i) {  }

}

但是,如果一个方法采用 refout 参数,而另一个方法不采用这两类参数,则可以进行重载,如下所示:

 

class RefOutOverloadExample

{

    public void SampleMethod(int i) {  }

    public void SampleMethod(out int i) {  }

}

示例


当希望方法返回多个值时,声明 out 方法很有用。使用 out 参数的方法仍然可以将变量用作返回类型,但它还可以将一个或多个对象作为 out 参数返回给调用方法。此示例使用 out 在一个方法调用中返回三个变量。请注意,第三个参数所赋的值为 Null。这样便允许方法有选择地返回值。

class OutReturnExample

{

    static void Method(out int i, out string s1, out string s2)

    {

        i = 44;

        s1 = "I've been returned";

        s2 = null;

    }

    static void Main()

    {

        int value;

        string str1, str2;

        Method(out value, out str1, out str2);

        // value is now 44

        // str1 is now "I've been returned"

        // str2 is (still) null;

    }

}

ref 和 out 传递数组

与所有的 out 参数一样,在使用数组类型的 out 参数前必须先为其赋值,即必须由被调用方为其赋值。例如:

 

static void TestMethod1(out int[] arr)

{

    arr = new int[10];   // definite assignment of arr

}

 

与所有的 ref 参数一样,数组类型的 ref 参数必须由调用方明确赋值。因此不需要由接受方明确赋值。可以将数组类型的 ref 参数更改为调用的结果。例如,可以为数组赋以 null 值,或将其初始化为另一个数组。例如:

static void TestMethod2(ref int[] arr)

{

    arr = new int[10];   // arr initialized to a different array

}

 

下面的两个示例说明 outref 在将数组传递给方法时的用法差异。

示例 1


在此例中,在调用方(Main 方法)中声明数组 theArray,并在 FillArray 方法中初始化此数组。然后将数组元素返回调用方并显示。

 

class TestOut

{

    static void FillArray(out int[] arr)

    {

        // Initialize the array:

        arr = new int[5] { 1, 2, 3, 4, 5 };

    }

 

    static void Main()

    {

        int[] theArray; // Initialization is not required

 

        // Pass the array to the callee using out:

        FillArray(out theArray);

 

        // Display the array elements:

        System.Console.WriteLine("Array elements are:");

        for (int i = 0; i < theArray.Length; i++)

        {

            System.Console.Write(theArray[i] + " ");

        }

    }

}

 

输出 1


Array elements are:

1 2 3 4 5

示例 2


在此例中,在调用方(Main 方法)中初始化数组 theArray,并通过使用 ref 参数将其传递给 FillArray 方法。在 FillArray 方法中更新某些数组元素。然后将数组元素返回调用方并显示。

class TestRef

{

    static void FillArray(ref int[] arr)

    {

        // Create the array on demand:

        if (arr == null)

        {

            arr = new int[10];

        }

        // Fill the array:

        arr[0] = 1111;

        arr[4] = 5555;

    }

 

    static void Main()

    {

        // Initialize the array:

        int[] theArray = { 1, 2, 3, 4, 5 };

 

        // Pass the array using ref:

        FillArray(ref theArray);

 

        // Display the updated array:

        System.Console.WriteLine("Array elements are:");

        for (int i = 0; i < theArray.Length; i++)

        {

            System.Console.Write(theArray[i] + " ");

        }

    }

}

 

输出 2


Array elements are:

1111 2 3 4 5555

posted @ 2011-07-15 07:36  meifage2  阅读(216)  评论(0编辑  收藏  举报