【问题标题】:What Is The Difference Between Passing Parameters By Output And By Reference In C#C#中通过输出和通过引用传递参数有什么区别
【发布时间】:2015-08-27 19:53:39
【问题描述】:

我一直在努力研究 C# 方法。可以通过三种方式将参数传递给 C# 方法。

值参数:此方法将参数的实际值复制到函数的形式参数中。在这种情况下,对函数内部参数所做的更改对参数没有影响。

引用参数:此方法将对参数的内存位置的引用复制到形参中。这意味着对参数所做的更改会影响参数。

输出参数:此方法有助于返回多个值。

我通过下面的示例代码了解了上述类型的传递参数。

using System;
namespace PassingParameterByReference
{
   class MethodWithReferenceParameters
   {
      public void swap(ref int x)
      {
        int temp = 5;
        x = temp;
      }
   
      static void Main(string[] args)
      {
         MethodWithReferenceParameters n = new MethodWithReferenceParameters();
         /* local variable definition */
         int a = 100;
         Console.WriteLine("Before swap, value of a : {0}", a);
         /* calling a function to swap the value*/
         n.swap(ref a);
         Console.WriteLine("After swap, value of a : {0}", a);
         Console.ReadLine();

      }
   }
}

上面的代码编译执行后,会产生如下结果:

交换前,a 的值:100

交换后,a 的值:5

通过这些代码,我可以理解通过引用将参数传递给方法。然后我检查下面的代码以了解通过输出将参数传递给方法。

using System;
namespace PassingParameterByOutput
{
   class MethodWithOutputParameters
   {
      public void swap(out int x)
      {
        int temp = 5;
        x = temp;
      }
   
      static void Main(string[] args)
      {
         MethodWithOutputParameters n = new MethodWithOutputParameters();
         /* local variable definition */
         int a = 100; 
         Console.WriteLine("Before swap, value of a : {0}", a);
         /* calling a function to swap the value */
         n.swap(out a);
         Console.WriteLine("After swap, value of a : {0}", a);
         Console.ReadLine();
       }
   }
}

上面的代码编译执行后,会产生如下结果:

交换前,a 的值:100

交换后,a 的值:5

这些示例代码以不同的方式执行相同的操作。而且我无法理解两种方法之间的区别。(通过输出和引用将参数传递给方法)。两个例子的输出是一样的。这个小区别是什么?

【问题讨论】:

  • 您声称第二个示例编译并运行,但是我得到两个编译器错误。在swap 中都关于使用未分配的参数 x 和 y。
  • 我修复了你所说的一个错误。以上交换方法有效。它们以不同的方式产生相同的输出。(通过输出和引用将参数传递给方法)

标签: c# methods parameters parameter-passing pass-by-reference


【解决方案1】:

输出参数不必像引用参数那样在调用方法之前初始化。

int someNum;
someMethod(out someNum); //works
someMethod(ref someNum); //gives compilation error

另外,Output参数需要在方法内设置或更改,引用参数则不需要。

【讨论】:

    【解决方案2】:

    使用“引用”参数,需要先分配值,然后方法才能使用它。您的示例中的 X 和 Y 需要在方法之外声明。 例如int x = 100; int y =200;

    使用“输出”参数,您无需为参数的值分配值即可使用它们。 X 和 Y 可以在您的示例中声明,但没有分配给它们的起始值。 例如int x; int y;

    【讨论】:

      【解决方案3】:

      输出参数需要在方法内部改变它的值,否则编译器会抛出错误。

      引用参数可能会或可能不会被方法更改其引用(引用对象)。

      值类型(结构中定义的类型)也不能通过引用传递。

      【讨论】:

        【解决方案4】:

        参考和输出参数非常相似。 唯一的区别是ref参数必须初始化。

        int myInt = 1;
        SomeMethod(ref myInt); //will work
        SomeMethod(out myInt); //will work
        
        int myInt;
        SomeMethod(ref myInt); //won't work
        SomeMethod(out myInt); //will work
        

        编译器实际上会以相同的方式查看ref 和out 关键字。例如,如果您不能重载方法,其中唯一的区别是 ref 和 out 关键字。

        以下方法签名将被编译器视为相同,因此这不是有效的重载。

        private void SomeMethod(ref int Foo){};
        private void SomeMethod(out int Foo){};
        

        【讨论】:

          【解决方案5】:

          看到这个What's the difference between the 'ref' and 'out' keywords?

          不同之处在于,对于 out 参数,您必须在离开方法之前设置它。因此,即使您在调用方法之前没有将其设置为任何值,编译器也知道它会在方法调用期间获得一个值。

          除了技术上的差异,为了有一个可读性好的代码,你应该在方法有多个输出时使用out。并在方法可能更新变量时使用 ref

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-11-19
            • 1970-01-01
            • 2010-10-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-07
            相关资源
            最近更新 更多