为什么必须使用“out”而不是ref?

时间:2010-05-29 19:21:31

标签: c# .net visual-studio visual-studio-2008 oop

我写了一些关于ref -out声明的代码块。我认为ref最有用。好。为什么我需要用完。我每次都可以使用ref:

namespace out_ref
{
    class Program
    {
        static void Main(string[] args)
        {
            sinifA sinif = new sinifA();
            int test = 100;
            sinif.MethodA(out test);
            Console.WriteLine(test.ToString());

            sinif.MethodB(ref test);
            Console.WriteLine(test.ToString());
            Console.ReadKey();
        }
    }

    class sinifA
    {

        public void MethodA(out int a)
        {
            a = 200;
        }

        int _b;
        public void MethodB(ref int b)
        {
            _b = b;
            b = 2*b;
        }
    }

}

5 个答案:

答案 0 :(得分:13)

是的,您每次都可以使用ref,但它们有不同的用途。 ref用于当参数既是输入又是输出时。当参数仅为输出时使用out。它可用于传递输入,但它使得函数的用户不需要在使用函数之前声明实例,因为您实际上说您将保证创建实例。当您从集合中获取值

时,它在TryXXX模式中特别有用

答案 1 :(得分:6)

如果附加了out的参数,则在将其传递给接受它的方法之前,不需要对其进行初始化。

The out keyword causes arguments to be passed by reference. 
This is like the ref keyword, except that ref requires that the variable be initialized 
before it is passed.

来自:http://msdn.microsoft.com/en-us/library/ee332485.aspx

答案 2 :(得分:3)

保证在函数期间初始化out参数。这为您的呼叫者提供了更严格的合同。它还允许您编写如下代码:

int i;
MyFunc(out i);
.. < use i > ..

未收到未初始化变量的编译错误。

答案 3 :(得分:1)

refout在内部以相同的方式处理,它们都通过引用传递变量。

不同之处在于初始化语义,谁负责确保变量具有有效的起始值,并且由编译器强制执行。

使用out参数,这是您调用的方法。在调用方法之前,通过引用传递的变量中的值是无关紧要的。如果您调用的方法的执行路径无法为其参数设置新值,编译器将会抱怨。这意味着在调用方法之前,变量中的任何值都会被保证被覆盖,即使它具有相同的值。

使用ref参数,它是调用的方法。变量的值将传递给被调用的方法,然后可以检查其参数并可选地更改它。编译器会抱怨调用在调用之前没有使用值初始化变量的方法。

基本上,这完全取决于编译器会抱怨什么。是调用代码必须确保变量中有值,还是被调用的代码。

答案 4 :(得分:0)

输出参数

除了通过引用传递值之外,还可以指定给定参数是out 使用out关键字的参数,其使用方式与ref关键字相同(作为修饰符) 到函数定义和函数调用中的参数)。实际上,这几乎给你带来了 与参考参数完全相同的行为,即参数值的结尾 函数执行返回到函数调用中使用的变量。但是,有重要的 差异:

  1. 使用未分配的变量作为ref参数是非法的,您可以使用 未分配的变量作为输出参数
  2. 必须将out参数视为使用它的函数的未分配值。
  3. 这意味着虽然允许在调用代码时使用指定的变量作为out参数, 当函数执行时,存储在该变量中的值将丢失。

    作为一个例子,考虑前面显示的MaxValue()函数的扩展,它返回 数组的最大值。稍微修改函数,以便获取元素的索引 具有数组中的最大值。为了简单起见,只需获取第一个索引 当有多个具有最大值的元素时出现此值。要执行此操作,请添加 通过修改函数的out参数如下:

    static int MaxValue(int[] intArray, out int maxIndex)
    

    { int maxVal = intArray [0]; maxIndex = 0; for(int i = 1; i&lt; intArray.Length; i ++) { if(intArray [i]&gt; maxVal) { maxVal = intArray [i]; maxIndex = i; } } return maxVal; }

    您可以使用此功能,如下所示:

    int[] myArray = {1, 8, 3, 6, 2, 5, 9, 3, 0, 2};
    

    int maxIndex; Console.WriteLine(“myArray中的最大值为{0}”, MaxValue(myArray,out maxIndex)); Console.WriteLine(“此值的第一个出现位于元素{0}”, maxIndex + 1);

    这导致以下结果:

    myArray中的最大值为9

    此值的第一次出现位于元素7

    当屏幕上显示maxIndex时,已添加一个值。这是为了 将索引转换为更易读的形式,以便将数组中的第一个元素称为元素 1,而不是元素0。