我正在创建一个函数,我需要传递一个对象,以便它可以被函数修改。有什么区别:

public void myFunction(ref MyClass someClass)

and

public void myFunction(out MyClass someClass)

我应该用哪个,为什么?


当前回答

简洁的回答。

ref和out关键字都用于引用传递。 关键字为ref的变量必须有一个值或必须引用一个对象 或者在它传递之前为null。 与ref不同,关键字为out的变量必须有一个值或必须 在对象传递后引用对象或null以及不需要 在传递之前有一个值或引用一个对象。

其他回答

由于您传递的是引用类型(类),因此不需要使用ref,因为默认情况下只传递对实际对象的引用,因此您总是要更改引用后面的对象。

例子:

public void Foo()
{
    MyClass myObject = new MyClass();
    myObject.Name = "Dog";
    Bar(myObject);
    Console.WriteLine(myObject.Name); // Writes "Cat".
}

public void Bar(MyClass someObject)
{
    someObject.Name = "Cat";
}

只要传入一个类,如果你想在方法中改变对象,就不必使用ref。

out:

在c#中,一个方法只能返回一个值。如果希望返回多个值,可以使用out关键字。out修饰符返回为return-by-reference。最简单的答案是使用关键字“out”从方法中获取值。

您不需要在调用函数中初始化该值。 必须在被调用的函数中赋值,否则编译器将报错。

ref:

在c#中,当你将一个值类型,如int, float, double等作为参数传递给方法参数时,它是按值传递的。因此,如果修改形参值,它不会影响方法调用中的实参。但是,如果您用“ref”关键字标记参数,它将反映在实际的变量中。

在调用函数之前,需要初始化变量。 为方法中的ref参数赋值不是强制的。如果不更改值,为什么需要将其标记为“ref”?

: return语句只能用于从函数中返回一个值。但是,使用输出参数,可以从一个函数返回两个值。输出参数类似于引用参数,只是它们将数据传输出方法而不是传输到方法中。

下面的例子说明了这一点:

using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void getValue(out int x )
      {
         int temp = 5;
         x = temp;
      }

      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* local variable definition */
         int a = 100;

         Console.WriteLine("Before method call, value of a : {0}", a);

         /* calling a function to get the value */
         n.getValue(out a);

         Console.WriteLine("After method call, value of a : {0}", a);
         Console.ReadLine();

      }
   }
}

裁判: 引用形参是对变量内存位置的引用。与值参数不同,通过引用传递参数时,不会为这些参数创建新的存储位置。引用参数表示与提供给方法的实际参数相同的内存位置。

在c#中,使用ref关键字声明引用参数。下面的例子说明了这一点:

using System;
namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void swap(ref int x, ref int y)
      {
         int temp;

         temp = x; /* save the value of x */
         x = y;   /* put y into x */
         y = temp; /* put temp into y */
       }

      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* local variable definition */
         int a = 100;
         int b = 200;

         Console.WriteLine("Before swap, value of a : {0}", a);
         Console.WriteLine("Before swap, value of b : {0}", b);

         /* calling a function to swap the values */
         n.swap(ref a, ref b);

         Console.WriteLine("After swap, value of a : {0}", a);
         Console.WriteLine("After swap, value of b : {0}", b);

         Console.ReadLine();

      }
   }
}

裁判上场又出局。

您应该优先使用out,只要它能满足您的需求。

裁判: ref关键字用于将参数作为引用传递。这意味着当该参数的值在方法中被更改时,它会反映在调用方法中。使用ref关键字传递的参数在传递给被调用方法之前必须在调用方法中初始化。

: out关键字也用于传递一个参数,如ref关键字,但参数可以在不给它赋值的情况下传递。使用out关键字传递的参数在返回调用方法之前必须在被调用方法中初始化。

public class Example
{
 public static void Main() 
 {
 int val1 = 0; //must be initialized 
 int val2; //optional

 Example1(ref val1);
 Console.WriteLine(val1); 

 Example2(out val2);
 Console.WriteLine(val2); 
 }

 static void Example1(ref int value) 
 {
 value = 1;
 }
 static void Example2(out int value) 
 {
 value = 2; 
 }
}

/* Output     1     2     

在方法重载中引用和out

ref和out不能同时用于方法重载。然而,ref和out在运行时的处理方式不同,但在编译时的处理方式相同(CLR在为ref和out创建IL时不区分两者)。