关于C#:.net中的ref和out参数之间的差异

Difference between ref and out parameters in .NET

本问题已经有最佳答案,请猛点这里访问。

.NET中的refout参数有什么区别?什么情况下一个比另一个更有用?什么是代码片段,其中一个可以使用,另一个不能使用?


它们几乎是相同的-唯一的区别是,作为out参数传递的变量不需要初始化,而是作为ref参数传递,它必须设置为某个值。

1
2
3
4
5
int x;
Foo(out x); // OK

int y;
Foo(ref y); // Error: y should be initialized before calling the method

ref参数用于可能修改的数据,out参数用于已经使用返回值的函数(如int.TryParse的附加输出的数据。


为什么C既有"Ref"又有"Out"?

获取out参数的方法的调用方不需要分配给在调用之前作为out参数传递的变量;但是,在返回之前,被调用方需要分配给out参数。

相反,REF参数最初被认为是由调用方分配的。因此,在使用之前,被调用方不需要分配给ref参数。引用参数同时传入和传出一个方法。

因此,out表示"出",而ref表示"进"和"出"。

这些参数与COM接口的[out][in,out]参数密切对应,out参数的优点是,在调用方法不需要调用预分配对象的情况下,调用方不需要传递预分配对象,这既避免了分配成本,也避免了与marshalin相关的任何成本。G(更有可能是COM,但在.NET中并不少见)。


这两种方法都被称为修改参数的方法。他们之间的区别是你打电话之前发生的事。

  • 表示参数在进入函数之前具有一个值。被称为函数的函数可以在任何时候读取或改变价值。参数输入,然后输出

  • 表示参数在进入功能之前没有任何官方价值。函数必须初始化。参数只有输出

这是我最喜欢看的方式:refIs to pass varians by reference.是要申报功能的二次回报值。就像你能写这个一样

1
2
3
4
5
// This is not C#
public (bool, string) GetWebThing(string name, ref Buffer paramBuffer);

// This is C#
public bool GetWebThing(string name, ref Buffer paramBuffer, out string actualUrl);

这是一份更详细的清单,列出了每一种备选办法的影响:

在呼唤方法之前:

Caller必须在将参数置于被称为方法之前设定参数值。

呼叫方法不需要在呼叫方法之前确定该论据的价值。事实上,任何现值都是公开的。

During the call:

被称为"方法"的方法随时都能读到这个论点。

被称为方法的参数必须在阅读之前初始化。

Remoted calls:

电流值马歇尔到远程呼叫。额外性能成本

没有什么东西被远程呼叫。快

技术上讲,你可以用ref代替out,但out允许你对论据的含义有更准确的理解,有时候这可以成为一个更有效的方法。


Example for out:Variable gets value initial after going into the method.随后,同一价值返回到主要方法。

ZZU1

Output:

10

=========================================================================

Example for Ref:Variabled should be initiatized before going into the method.后一价值或修改价值将返回主要方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
namespace outreftry
{
    class outref
    {
        static void Main(string[] args)
        {
            yyy a = new yyy(); ;

            int i = 0;

            a.abc(ref i);

            System.Console.WriteLine(i);
        }
    }
    class yyy
    {

        public void abc(ref int i)
        {
            System.Console.WriteLine(i);
            i = 10;

        }

    }
}

BLCK1/

===========================================================

希望它现在清晰。


Ref and out parameters:

参数被用来返回相同的变量中的值,您将其作为一个方法的参数。当你的方法需要回报的时候,这些参数非常有用。

你必须在凯里法体中指定参数值,否则无法编译。

Ref Parameter : It has to be initialized before passing to the Method.
The ref keyword on a method parameter causes a method to refer to the same variable that was passed as an input parameter for the same method. If you do any changes to the variable, they will be reflected in the variable.

1
2
int sampleData = 0;
sampleMethod(ref sampleData);

参考参数

1
2
3
4
5
6
7
8
9
10
public static void Main()
{
 int i = 3; // Variable need to be initialized
 sampleMethod(ref i );  
}

public static void sampleMethod(ref int sampleData)
{
 sampleData++;
}

Out Parameter : It is not necessary to be initialized before passing to Method.
The out parameter can be used to return the values in the same variable passed as a parameter of the method. Any changes made to the parameter will be reflected in the variable.

1
2
 int sampleData;
 sampleMethod(out sampleData);

输出参数

1
2
3
4
5
6
7
8
9
10
11
public static void Main()
{
 int i, j; // Variable need not be initialized
 sampleMethod(out i, out j);
}
public static int sampleMethod(out int sampleData1, out int sampleData2)
{
 sampleData1 = 10;
 sampleData2 = 20;
 return 0;
}

  • 在通过之前,变量需要被初始化。
  • 在功能实现中设置变量需要
  • 参数可以被视为附加回报变量(不输入)
  • 参数可以同时考虑输入和输出变量。


出:

在C中,一个方法只能返回一个值。如果要返回多个值,可以使用out关键字。out修饰符作为引用返回。最简单的答案是,关键字"out"用于从方法中获取值。

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

裁判:

在C中,当您将一个值类型(如int、float、double等)作为参数传递给方法参数时,它是通过value传递的。因此,如果修改参数值,它不会影响方法调用中的参数。但是,如果用"ref"关键字标记参数,它将反映在实际变量中。

  • 在调用函数之前需要初始化变量。
  • 方法中的ref参数不必指定任何值。如果不更改值,需要将其标记为"Ref"吗?

Specifies that the parameter is an exput parameters,I.E.It has no value until it is explicitly set by the method.

具体说明,价值是一个有价值的参照,而你的价值在方法中是可以改变的。


函数中不需要设置引用参数,而out参数必须在退出函数之前绑定到一个值。作为输出传递的变量也可以在不初始化的情况下传递给函数。


out参数是添加了特殊Out()属性的ref参数。如果C方法的参数声明为out,编译器将要求在读取参数之前和返回方法之前写入该参数。如果C调用一个参数包含Out()属性的方法,为了决定是否报告"未定义变量"错误,编译器将假设在调用该方法之前立即写入该变量。请注意,由于其他.NET语言没有对Out()属性附加相同的含义,因此使用out参数调用例程可能会使相关变量不受影响。如果一个变量在明确指定之前被用作out参数,C编译器将生成代码,以确保在使用之前在某个点清除它,但是如果这样的变量离开并重新进入作用域,就不能保证它会再次被清除。


ref关键字用于按引用传递值。(这并不排除传递的值是值类型或引用类型)。使用out关键字指定的输出参数用于从方法返回值。

代码中的一个关键区别是,必须在方法中设置输出参数的值。这不是引用参数的情况。

有关更多详细信息,请访问http://www.blackwasp.co.uk/csharptmethodparameters.aspx


out参数由调用的方法初始化,ref参数在调用方法之前初始化。因此,当您只需要获取二次返回值时,使用out参数,ref参数用于获取值,并可能返回对该值的更改(二次返回到主返回值)。


Out在C 7中得到了一种新的更简洁的语法。https://docs.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7更多表达式主体成员更令人兴奋的是C 7元组增强,它比使用ref和out imho更优雅。


当在方法声明中声明out参数时,方法体应在返回之前为out变量赋值。因此,被调用方法的职责是在out参数返回之前将值赋给它。

当在方法中声明引用参数时,调用方法时传递的参数应该已经分配了该值。因此,调用方有责任在调用方法之前为ref参数赋值。


REF可能会在NULL上阻塞,因为它可能期望修改一个现有的对象。out需要空值,因为它正在返回一个新对象。


C中的out和ref参数有一些很好的例子。

概述的基本区别是,传入时不需要初始化out参数,而ref参数需要初始化。


它们有细微的不同。

out参数在传递给方法之前不需要由被调用方初始化。因此,任何具有out参数的方法

  • 在为参数赋值之前无法读取该参数
  • 返回前必须为其赋值

这用于需要覆盖其参数的方法,而不考虑其先前的值。

ref参数在传递给方法之前必须由被调用方初始化。因此,任何具有ref参数的方法

  • 可以在分配前检查该值
  • 可以返回原值,未经触摸

这用于必须(例如)检查其值并对其进行验证或规范化的方法。


out和ref完全相同,只是out变量在发送到深渊之前不需要初始化。我没那么聪明,我是从msdn图书馆偷来的。

然而,更明确地说,修饰符的含义是,如果在代码中更改该变量的引用,out和ref也会导致调用变量更改引用。在下面的代码中,当newguy从对dostuff的调用中返回时,ceo变量将作为对newguy的引用。如果不是引用(或不引用),引用将不会被更改。

1
2
3
4
5
6
7
8
9
10
11
private void newEmployee()
{
    Person ceo = Person.FindCEO();
    doStuff(ref ceo);
}

private void doStuff(ref Person employee)
{
    Person newGuy = new Person();
    employee = newGuy;
}