可选输出参数

Jer*_*gly 64 c# c#-4.0

在C#4中,有一个提供可选输出参数的好方法吗?

Cam*_*ron 62

虽然你总是可以使用另一个不接受输出参数的方法重载该方法,但事实并非如此.

  • 在C#7.0中你可以做`Foo(out string dummy);`甚至更好`Foo(out _);`(下划线) (5认同)
  • 任何想法如何比`{string dummy;更优雅地处理可选参数; 返回Foo(out dummy); 在没有输出参数的重载中? (3认同)
  • 事实上这是可能的,表明它在语言设计中应该是可选的。这似乎是一个不错的解决方案。虽然,它不允许我将输出参数放在其他可选参数之后,如果我希望重载具有相同的参数顺序,这可能会导致拼写错误 (3认同)
  • @Louis:不,这可能就是我做过的! (2认同)
  • 这是很多额外的样板代码。 (2认同)

cod*_*zen 7

没有.

要使其"可选",在您不需要在方法中指定值的意义上,您可以使用ref.

  • `ref`参数是一个非常不同的用例.如果调用者没有指定一个可选参数,则传递一个特定的值 - 使用ref参数,调用者总是指定一个值,无论他们是否觉得他们已经指定了它.`ref`始终指向有效的内存位置,有效的内存位置始终包含_something_.充其量,这只是一个神奇的值,没有默认规范的好处,说"默认值是X". (5认同)
  • 是的,这个答案不是一个设计判断,这就是为什么我添加了"在某种意义上"的限定词. (4认同)

小智 7

使用OptionalAttribute修饰参数也不起作用.要扩展上一个示例,您将获得以下内容:

private void Func(
    [Optional] out int optional1, 
    [Optional] out string optional2) 
{ /* ... */ }
Run Code Online (Sandbox Code Playgroud)

请注意,上面将编译(可能不幸).但是,尝试编译:

Func(out i);
Run Code Online (Sandbox Code Playgroud)

除非明确提供具有单参数签名的重载,否则将失败.

(理论上)使上述工作成为一个重大问题.当调用带有省略的可选参数的方法时,将创建包含所有参数值的堆栈帧,并使用指定的默认值填充缺失值.

但是,"out"参数是引用,而不是值.如果该参数是可选的并且未提供,那么它将引用哪个变量?编译器仍然需要强制要求在从方法正常返回之前填充"out"参数,因为编译器不知道调用者指定了哪个(如果有的话)可选参数.这意味着必须传递对某处虚拟变量的引用,因此该方法需要填充.管理这个虚拟变量空间会给编译器的编写者带来令人讨厌的麻烦.我并不是说要弄清楚它是如何工作的细节是不可能的,但是体系结构的影响非常大,以至于微软可以理解地传递了这个功能.