ref和out在运行时有何不同?

时间:2019-01-17 13:59:12

标签: c# ref out

在许多文章中,他们给出了ref和out out的工作方式相同。即使在编译时也以相同的方式识别两者,但在运行时(CLR)却有所不同谁能解释它的不同之处?和功能?

我在这段代码中也尝试过

public static void Main()
    {
        int par = 7;
        Program x= new Program();
        x.RefMethod(out par);
        Console.WriteLine(par);
        x.RefMethod1(ref par);
        Console.WriteLine(par);

        Console.ReadLine();
    }
    public void RefMethod(out int i)
    {
        i = 10;

    }
    public void RefMethod1(ref int i)
    {
        i = 20;
    }

ILDASM用于refmethod:

method public hidebysig instance void  RefMethod([out] int32& i) cil managed
{
  // Code size       6 (0x6)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.1
  IL_0002:  ldc.i4.s   10
  IL_0004:  stind.i4
  IL_0005:  ret
} // end of method Program::RefMethod

针对Refmethod1的ILDASM:

method public hidebysig instance void  RefMethod1(int32& i) cil managed
{
  // Code size       6 (0x6)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.1
  IL_0002:  ldc.i4.s   20
  IL_0004:  stind.i4
  IL_0005:  ret
} // end of method Program::RefMethod1

上面的内容清楚地表明两者在某一点上是不同的,即在该方法初始化时。请问有人可以帮助我解决我的问题吗?

请任何人清楚地回答问题。我仍然没有得到答案:(

2 个答案:

答案 0 :(得分:1)

ref和out之间的区别不在CLR中,而在C#语言中。 Ref和Out的不同之处在于,每个编译器的“编译器要求不同的行为”。在编译时也不允许方法重载。

从代码中可以看到,唯一的变化是地址引用,特别是此行的地址(如果您输入值10,则该值为10)。

IL_0002:  ldc.i4.s   20

答案 1 :(得分:1)

Gauravsa's answer是正确的。没有运行时差异。

您提到https://www.c-sharpcorner.com/UploadFile/ff2f08/ref-vs-out-keywords-in-C-Sharp/,其中指出:

  

在运行时对ref和out的处理方式有所不同,   在编译时将其视为相同,因此如果以下情况不能重载方法   一种方法将参数作为ref,另一种方法将参数作为   一个。

该文章的作者可能读过https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-parameter-modifier,其中指出:

  

尽管in,ref和out关键字会导致运行时不同   行为,它们不被视为方法签名的一部分   编译时间。因此,如果唯一的方法不能重载   区别在于,一种方法采用ref或in参数,而另一种采用   接受out参数。

我个人同意jmoreno,他认为MSDN应该使用短语“要求不同的行为”而不是“原因不同的行为”。

在多个地方看到这种解释也就不足为奇了。可能许多尝试使用Microsoft文档作为其主要信息来源的作者都提供了相同的误导性解释。