C# .NET中ref和out参数之间的差异

C# .NET中ref和out参数之间的差异,c#,.net,C#,.net,.NET中的ref和out参数之间有什么区别?在什么情况下,一个比另一个更有用?如果一个代码段可以使用而另一个不能使用,那么会是什么样的代码段?ref可能会被null阻塞,因为它可能希望修改现有对象。out需要null,因为它返回一个新对象。Ref参数不需要在函数中设置,而out参数必须在退出函数之前绑定到一个值。作为out传递的变量也可以在不初始化的情况下传递给函数。out参数由调用的方法初始化,ref参数在调用该方法之前初始化。因此,out参数用于仅需要获取辅助返回值时,ref参数用于获取值

.NET中的
ref
out
参数之间有什么区别?在什么情况下,一个比另一个更有用?如果一个代码段可以使用而另一个不能使用,那么会是什么样的代码段?

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

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

out
参数由调用的方法初始化,
ref
参数在调用该方法之前初始化。因此,
out
参数用于仅需要获取辅助返回值时,
ref
参数用于获取值并可能返回对该值的更改(辅助返回主返回值).

它们几乎相同-唯一的区别是,作为
输出
参数传递的变量不需要初始化,但作为
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
)的附加输出的数据,该函数已使用返回值进行某些操作。

int x;
Foo(out x); // OK

int y;
Foo(ref y); // Error: y should be initialized before calling the method
获取out参数的方法的调用者不需要在调用之前分配给作为out参数传递的变量;但是,被调用方必须在返回之前分配out参数


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

因此,
out
表示out,而
ref
表示in和out


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

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

代码中的一个关键区别是必须在方法中设置输出参数的值。ref参数的情况并非如此

有关更多详细信息,请参阅

这有一些很好的示例


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

out和ref完全相同,只是out变量在发送到深渊之前不需要初始化。我没那么聪明,我是从MSDN库抄袭的:)

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

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;

        }

    }
}
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;

        }

    }
}
输出:

十,

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

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

        }

    }
}
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
    变量
    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; 
    }