.NET中ref和out参数之间的区别

时间:2008-09-25 18:57:27

标签: c# .net

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

18 个答案:

答案 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)

refout都允许被调用方法修改参数。它们之间的差异就是在你打电话之前发生的事情。

  • 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)

参考和输出参数:

outref参数用于返回同一变量中的值,并将其作为方法的参数传递。当您的方法需要返回多个值时,这两个参数都非常有用。

你必须在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”用于从方法中获取值。

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

REF:

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

  • 在调用函数之前,需要初始化变量。
  • 不必为方法中的ref参数指定任何值。如果您不更改该值,需要将其标记为“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更优雅。