.NET中ref
和out
参数之间有什么区别?一个人比另一个人更有用的情况是什么?什么是一个可以使用而另一个不能使用的代码片段?
答案 0 :(得分:488)
它们几乎相同 - 唯一的区别是您作为out
参数传递的变量不需要初始化,而是将其作为ref
参数传递它必须是设置为某种东西。
int x;
Foo(out x); // OK
int y;
Foo(ref y); // Error: y should be initialized before calling the method
Ref
参数用于可能被修改的数据,out
参数用于数据,该数据是函数的额外输出(例如int.TryParse
),它们已经在使用返回值
答案 1 :(得分:128)
Why does C# have both 'ref' and 'out'?
在调用之前,不需要将带out参数的方法的调用者分配给作为out参数传递的变量;但是,被调用者需要在返回之前分配out参数。
相比之下,ref参数最初由调用者分配。因此,被调用者在使用之前不需要分配给ref参数。参数传入和传出方法。
因此,out
表示out,而ref
表示输入和输出。
这些参数与COM接口的[out]
和[in,out]
参数紧密对应,out
参数的优点是调用者不需要传递预分配的对象调用方法所需要的 - 这可以避免分配成本,以及可能与编组相关的任何成本(更可能是COM,但在.NET中并不罕见)。
答案 2 :(得分:82)
ref
和out
都允许被调用方法修改参数。它们之间的差异就是在你打电话之前发生的事情。
ref
表示参数在进入函数之前有的值。被调用的函数可以随时读取和/或更改值。 参数进入,然后出现
out
表示该参数在进入函数之前没有官方值。被调用的函数必须初始化它。 参数仅出局
以下是我最喜欢的方式:ref
是通过引用传递变量。 out
是为函数声明次要返回值。就像你能写下这个:
// 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);
以下是每种备选方案效果的更详细列表:
ref
:调用者必须先设置参数的值,然后再将其传递给被调用的方法。
out
:调用方法之前,不需要调用方法来设置参数的值。最有可能的,你不应该。实际上,任何当前值都将被丢弃。
ref
:被调用的方法可以随时读取参数。
out
:被调用的方法必须在读取之前初始化参数。
ref
:当前值被编组到远程调用。额外的性能成本。
out
:没有任何内容传递给远程调用。更快。
从技术上讲,您可以始终使用ref
代替out
,但out
可以让您更准确地了解参数的含义,有时它可能会很多效率更高。
答案 3 :(得分:16)
OUT示例:变量在进入方法后初始化值。稍后,相同的值将返回到main方法。
namespace outreftry
{
class outref
{
static void Main(string[] args)
{
yyy a = new yyy(); ;
// u can try giving int i=100 but is useless as that value is not passed into
// the method. Only variable goes into the method and gets changed its
// value and comes out.
int i;
a.abc(out i);
System.Console.WriteLine(i);
}
}
class yyy
{
public void abc(out int i)
{
i = 10;
}
}
}
输出:
10
===============================================
参考示例:应该在进入方法之前初始化变量。稍后相同的值或修改后的值将返回到main方法。
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;
}
}
}
输出:
0 10
=================================
希望现在明白。
答案 4 :(得分:9)
out
和ref
参数用于返回同一变量中的值,并将其作为方法的参数传递。当您的方法需要返回多个值时,这两个参数都非常有用。
你必须在calee方法体中为out参数赋值,否则该方法不会被编译。
参考参数:必须在传递给Method之前进行初始化。 方法参数上的
ref
关键字使方法引用作为同一方法的输入参数传递的同一变量。如果对变量进行任何更改,它们将反映在变量中。int sampleData = 0; sampleMethod(ref sampleData);
参考参数Ex
public static void Main()
{
int i = 3; // Variable need to be initialized
sampleMethod(ref i );
}
public static void sampleMethod(ref int sampleData)
{
sampleData++;
}
Out参数:在传递给Method之前无需初始化。
out
参数可用于返回作为方法参数传递的同一变量中的值。对参数所做的任何更改都将反映在变量中。int sampleData; sampleMethod(out sampleData);
Ex Out Out参数
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;
}
答案 5 :(得分:9)
ref
变量之前,需要对其进行初始化。out
变量out
参数可以被认为是额外的返回变量(不是输入)ref
参数可以被视为输入和输出变量。 答案 6 :(得分:7)
在C#中,方法只能返回一个值。如果要返回多个值,可以使用out关键字。 out修饰符作为引用返回返回。最简单的答案是关键字“out”用于从方法中获取值。
在C#中,当您将一个值类型(如int,float,double等)作为参数传递给method参数时,它将按值传递。因此,如果修改参数值,则不会影响方法调用中的参数。但是如果用“ref”关键字标记参数,它将反映在实际变量中。
答案 7 :(得分:4)
不需要在函数中设置Ref参数,而在退出函数之前必须将out参数绑定到一个值。作为输出传递的变量也可以在没有初始化的情况下传递给函数。
答案 8 :(得分:4)
out
指定参数是输出参数,即在方法明确设置之前它没有值。
ref
指定该值是具有值的引用,并且您可以在方法内更改其值。
答案 9 :(得分:1)
ref关键字用于通过引用传递值。 (这并不排除传递的值是值类型或引用类型)。使用out关键字指定的输出参数用于从方法返回值。
代码中的一个关键区别是您必须在方法中设置输出参数的值。参数不是这种情况。
有关详细信息,请查看http://www.blackwasp.co.uk/CSharpMethodParameters.aspx
答案 10 :(得分:1)
out
参数由被调用的方法初始化,ref
参数在调用方法之前被初始化。因此,当您只需要获取辅助返回值时,将使用out
个参数,ref
参数用于获取值并且可能会返回对该值的更改(其次到主要的回报值)。
答案 11 :(得分:1)
out
参数是ref
参数,添加了特殊的Out()
属性。如果C#方法的参数声明为out
,则编译器将要求在读取参数之前和方法返回之前写入参数。如果C#调用其参数包含Out()
属性的方法,则为了决定是否报告“未定义变量”错误,编译器将假定在调用方法之前立即写入变量。请注意,由于其他.net语言不会将相同含义附加到Out()
属性,因此调用具有out
参数的例程可能会使有问题的变量不受影响。如果变量在明确赋值之前用作out
参数,则C#编译器将生成代码以确保它在使用之前的某个时刻被清除,但是如果这样的变量离开并重新进入范围,不能保证会再次清除。
答案 12 :(得分:0)
out和ref完全相同,只是在将变量发送到深渊之前不必初始化out变量。我不那么聪明,我从MSDN库中删除了它:)。
为了更明确地说明它们的用法,修饰符的含义是,如果你在代码中更改了该变量的引用,out和ref将导致你的调用变量也改变引用。在下面的代码中,ceo变量将在调用doStuff后返回newGuy。如果不是ref(或out),则不会更改引用。
private void newEmployee()
{
Person ceo = Person.FindCEO();
doStuff(ref ceo);
}
private void doStuff(ref Person employee)
{
Person newGuy = new Person();
employee = newGuy;
}
答案 13 :(得分:0)
此 The out and ref Paramerter in C# 有一些很好的例子。
概述的基本差异是,out
参数在传入时不需要初始化,而ref参数则需要初始化。
答案 14 :(得分:0)
在方法声明中声明out parameter时,方法体应在返回之前为out变量赋值。因此,被调用方法的责任是在返回之前将值分配给out参数。
当在方法中声明ref parameter时,在调用方法时传递的参数应该已赋值。因此调用者有责任在调用方法之前为ref参数赋值。
答案 15 :(得分:0)
ref可能会阻塞null,因为它可能希望修改现有对象。 out期望null,因为它返回一个新对象。
答案 16 :(得分:0)
他们略有不同。
在传递给方法之前,被调用者不需要初始化out
参数。因此,任何具有out
参数
这用于需要覆盖其参数的方法,无论其先前的值如何。
在将被传递给方法之前,必须由被调用者初始化ref
参数。因此,任何具有ref
参数
这用于必须(例如)检查其值并对其进行验证或对其进行标准化的方法。
答案 17 :(得分:0)
out在C#7中获得了一个新的更多succint语法 https://docs.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7#more-expression-bodied-members 更令人兴奋的是C#7元组增强功能,比使用ref和IMHO更优雅。