简体   繁体   English

在C#中通过输出和参考传递参数之间的区别是什么

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

I have been making an effort on C# methods. 我一直在努力研究C#方法。 There are three ways that parameters can be passed to a C# methods. 有三种方法可以将参数传递给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. 输出参数 :此方法有助于返回多个值。

I understood above types of passing parameters with below sample codes. 我通过以下示例代码了解了上述类型的传递参数。

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

      }
   }
}

When the above code is compiled and executed, it produces the following result: 编译并执行上述代码时,会产生以下结果:

Before swap, value of a : 100 在交换之前,a的值为:100

After swap, value of a : 5 交换后,a:5的值

With this codes i could understand to pass parameters to methods by reference. 使用此代码,我可以理解通过引用将参数传递给方法。 And then i examine below code to understand passing parameters to methods by output. 然后我检查下面的代码,以了解输出方法的传递参数。

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

When the above code is compiled and executed, it produces the following result: 编译并执行上述代码时,会产生以下结果:

Before swap, value of a : 100 在交换之前,a的值为:100

After swap, value of a : 5 交换后,a:5的值

These sample codes make same action with different ways. 这些示例代码以不同的方式执行相同的操作。 And i can't understand difference between two approaches.( Passing Parameters To Method By Output And By Reference). 并且我无法理解两种方法之间的区别。(通过输出和参考将参数传递给方法)。 Two example's output is the same. 两个例子的输出是相同的。 What is this small difference? 这个小差异是什么?

Output parameters dont have to be initialized before the method is called like it is the case for reference parameters. 在调用方法之前不必初始化输出参数,就像参考参数的情况一样。

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

Furthermore, the Output parameter needs to be set or changed within the method, which is not necessary for reference parameters. 此外,需要在方法中设置或更改输出参数,这对于参考参数不是必需的。

With "Reference" parameters, the value needs to be assigned before a method can use it. 使用“Reference”参数时,需要在方法可以使用之前分配值。 X and Y in your examples would have needed to have been declared outside the method. 您的示例中的X和Y需要在方法之外声明。 eg int x = 100; int y =200; 例如, int x = 100; int y =200; int x = 100; int y =200;

With "Output" parameters, the value for your parameters don't have to be assigned a value before you can use them. 使用“输出”参数时,不必为参数值分配值,然后才能使用它们。 X and Y could have been declared in your example with no starting values assigned to them. 可能已在您的示例中声明了X和Y,但没有为其分配起始值。 eg int x; int y; 例如int x; int y; int x; int y;

An output parameter needs to have it's value changed inside the method otherwise the compiler will throw an error. 输出参数需要在方法内更改它的值,否则编译器将抛出错误。

The reference parameter may or may not have it's reference (reference objects) changed by the method. 参考参数可以或可以不具有由该方法改变的参考(参考对象)。

Also value types (types defined in structs) cannot be passed by reference. 此外,值类型(在结构中定义的类型)不能通过引用传递。

See this What's the difference between the 'ref' and 'out' keywords? 请参阅“ref”和“out”关键字之间的区别是什么?

The difference is that for an out parameter you have to set it before leaving the method. 不同之处在于,对于out参数,您必须在离开方法之前进行设置。 So even if you dont set it to any value before calling the method the compiler knows that it will get a value during the method call. 因此,即使您在调用方法之前未将其设置为任何值,编译器也会知道它将在方法调用期间获取值。

Appart from technical differences, to have a good readable code, you should use out when the method has more than one output. 从技术差异来看,要有一个良好的可读代码,你应该在方法有多个输出时使用。 And use ref when the method just may update the variable 并且当方法可以更新变量时使用ref

Reference and Output parameters are very similar. 参考和输出参数非常相似。 The only difference is that ref parameters must be initialized. 唯一的区别是必须初始化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

The compiler will actually view the ref and out keywords the same. 编译器实际上会查看refout关键字。 For example if you cannot have overloaded methods where the only difference is the ref and out keywords. 例如,如果您不能重载方法,唯一的区别是refout关键字。

The following methods signatures will be viewed the same by the compiler, so this would not be a valid overload. 编译器将查看以下方法签名,因此这不是有效的重载。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM