C#中按输出和按引用传递参数有什么区别

What Is The Difference Between Passing Parameters By Output And By Reference In C#

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

Value parameters : This method copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument.

Reference parameters : This method copies the reference to the memory location of an argument into the formal parameter. This means that changes made to the parameter affect the argument.

Output parameters : This method helps in returning more than one value.

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

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();

      }
   }
}

以上代码编译执行后,结果如下:

Before swap, value of a : 100

After swap, value of 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();
       }
   }
}

以上代码编译执行后,结果如下:

Before swap, value of a : 100

After swap, value of a : 5

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

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

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

此外,Output参数需要在方法内设置或更改,参考参数则不需要。

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

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

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

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

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

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

对于"Reference"参数,需要先赋值,方法才能使用它。您示例中的 X 和 Y 需要在方法外部声明。 例如int x = 100; int y =200;

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

参考和输出参数非常相似。 唯一的区别是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

编译器实际上会将 refout 关键字视为相同。例如,如果您不能重载方法,唯一的区别是 refout 关键字。

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

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