out参数不能是可选的是什么原因?

时间:2015-05-06 07:53:14

标签: c#

我不明白为什么在调用带有out参数的方法时必须声明变量,即使我不关心方法提供的out

对我来说,它似乎类似于调用返回值为bool Foo()但不消耗Foo();的方法。将out参数标记为可选的可能性会使我的代码更清晰,或者会让API开发人员在没有方法out参数的情况下编写重载。

那么,out参数不可选是什么原因?

4 个答案:

答案 0 :(得分:3)

我认为没有一个真正的理由不能。也许原因只是:因为它是记录在案的。

据我所知,没有任何编译器魔法让out变得特别。看看这个CIL代码:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       17 (0x11)
  .maxstack  1
  .locals init ([0] int32 y)
  IL_0000:  nop
  IL_0001:  ldloca.s   y
  IL_0003:  call       void ConsoleApplication15.Program::X(int32&)
  IL_0008:  nop
  IL_0009:  ldloc.0
  IL_000a:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_000f:  nop
  IL_0010:  ret
} // end of method Program::Main

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

源自此方法:

public static void X(out int i)
{
    i = 10;
}

static void Main(string[] args)
{
    int y;
    X(out y);

    Console.WriteLine(y);
}

如您所见,变量在调用方法中分配,值通过“引用”传递。定义out参数'just'的默认值会中断检查是否设置了值(因为它已经存在)。

另外,作为Damien_The_Unbeliever commented,它可能只是在可选参数的初始构建中被忽略/跳过的功能,因为out已经存在。

答案 1 :(得分:1)

Out参数是编译技巧。 CLR世界中没有任何称为out参数的东西。它实际上是传递给方法的ref参数。

区别在于编译器将确保在方法退出之前分配值。就是这样。

因此,当您需要使用ref / out参数调用方法时,您不需要值,而是需要对变量/字段的引用。

对于可选参数,c#编译器在调用方法时会传递默认值,但在这里你不能;你需要一个参考。

如果编译器必须支持此功能,则必须为您创建变量,通过引用传递它并忽略结果。正如你所看到的,这是一个丑陋的事情,因此我们没有这个功能。

答案 2 :(得分:0)

"当前" C#编译器(前Roslyn)非常复杂,在Microsoft,他们只在严格必要时才尝试修改它。 COM互操作所需的可选参数,因此他们添加了它们。或许可选择输出参数。

我们希望通过Roslyn,编译器可以更快地进步,我们将进入语法bloath的新时代: - )

有人在Roslyn github上对此进行了功能请求:https://github.com/dotnet/roslyn/issues/186

答案 3 :(得分:0)

我认为这个讨论有两个层次。技术水平和功能水平。

在技术层面上,问题应该是:它是否可能/可以完成?在这种情况下,答案是肯定的。对于编译器,很容易创建一个隐藏的局部,并使用可选的out参数调用该方法,并引用这个隐藏的局部。

在功能层面,我们应该问自己:这是我们真正想要的吗?

我的意见是:为什么不呢?当我们调用一个函数时,我们已经忽略了返回值而没有结果。那么为什么我们不允许(自动)忽略来自(可选)out-parameter的值?

此外,我们可能会遇到与该方法的其他重载冲突,但作为状态,我们在使用选项时已经存在这些冲突,所以没有新的。

最后,由C#的设计者决定。他们应该回答这两个问题:这是否可能,我们是否想要这个?