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

时间:2020-03-06 14:44:29  来源:igfitidea点击:

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

解决方案

ref可能会阻塞null,因为它可能希望修改现有对象。 out期望为null,因为它正在返回一个新对象。

不需要在函数中设置Ref参数,而在退出函数之前,必须将out参数绑定到一个值。传递出去的变量也可以不初始化而传递给函数。

out参数是通过调用的方法初始化的,ref参数是在调用该方法之前初始化的。因此,当我们只需要获取辅助返回值时,将使用out参数,而ref参数将用于获取值并有可能将更改返回至该值(其次是返回主返回值)。

它们几乎相同,唯一的区别是,我们不需要初始化作为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")的数据,这些数据已经使用了某些东西的返回值。

为什么查韦斯既"引用"又"退出"?

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

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

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

这些参数与COM接口的[out]和[in,out]参数紧密对应,out参数的优点在于,在调用者不需要传递预分配对象的情况下,调用者无需传递预分配对象。调用此方法既避免了分配成本,也避免了与封送处理相关的任何成本(与COM在一起更有可能,但在.NET中并不罕见)。

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

代码中的一个关键区别是我们必须在方法内设置输出参数的值。 ref参数不是这种情况。

有关更多详细信息,请参见http://www.blackwasp.co.uk/CSharpMethodParameters.aspx

这是Chas中的out和ref Paramerter的一些很好的例子。

概述的基本区别在于,传入参数无需初始化out参数,而ref参数则需要初始化。

out和ref完全相同,不同之处在于out变量在发送到深渊之前不必初始化。我不是那么聪明,我从MSDN库中窃取了它:)。

为了更明确地说明它们的用法,修饰符的含义是,如果我们在代码中更改了该变量的引用,则out和ref也会导致调用变量也更改引用。在下面的代码中,一旦ceo变量从对doStuff的调用返回后,它将成为对newGuy的引用。如果不是用于引用(或者引用),则不会更改引用。

private void newEmployee()
{
    Person ceo = Person.FindCEO();
    doStuff(ref ceo);
}

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

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可以使我们更精确地理解参数的含义,有时它可以使效率更高。

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

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

Ref的示例:在进入方法之前,应先初始化变量。稍后,相同的值或者修改后的值将返回到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

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

希望现在清除。

  • ref变量需要在传入之前进行初始化。
  • 我们需要在函数实现中设置一个out变量
  • 可以将" out"参数视为添加的返回变量(非输入)
  • ref参数可以被视为输入和输出变量。

out指定该参数为输出参数,即在该方法显式设置之前,它没有任何值。

ref指定该值是具有值的引用,我们可以在方法内部更改其值。