【问题标题】:Explicit array for params with optional arguments? [duplicate]带有可选参数的参数的显式数组? [复制]
【发布时间】:2013-12-28 04:44:46
【问题描述】:
void Main()
{
    //Thing(x:1, s:string.Empty, hello:new Hello(), new Hello());
    Thing(x:1, s:string.Empty, hello:new[]{ new Hello(), new Hello()});
}

public void Thing(int x, string s = "", params Hello[] hello)
{
}

public class Hello { }

为什么我需要指定一个数组来使参数在与可选参数一起使用时起作用,还是我这样做?使用标签的唯一原因是因为我最初想排除可选参数

【问题讨论】:

标签: c#


【解决方案1】:

因为这就是params 的工作方式——从技术上讲,它是一个数组参数,编译器将从参数列表中为您生成。当前的 C# 规范不支持将多个值传递给一个命名参数而不捆绑它们。如果您想使用参数名称来批量多个值,则必须将参数捆绑在一个数组中。

这些应该可以工作:

Thing(x:1, hello:new[]{ new Hello(), new Hello()}); // 2 values
Thing(x:1, hello:new Hello());  // one value
Thing(x:1); // no values

如果您认为相对于实现它所需的成本,这对编译器来说是一个有价值的补充,那么请随时在Microsoft Connect上发表建议 p>

【讨论】:

  • @D Stanley 另外,这是当前的编译器实现,有解释吗?
  • 没有人在编译器中实现它——这就是原因。我的猜测是没有人建议它,或者提供的 价值 不能证明实施它的 成本 是合理的——无论是机会成本、技术成本还是对其他功能的影响。功能不是免费的。
  • @Jaycee 我能想到几个更紧迫的增强功能,你可以重载你的函数。
  • 嗯,它不在编译器中,因为它不在规范中。但老实说,由于在编译器中实现它的成本,它可能不在规范中。
【解决方案2】:

你可以这样做,

Thing(1, string.Empty, new Hello(), new Hello());

因为您使用的是params

就此而言,所有这些都是兼容的。

Thing(1);
Thing(2, string.Empty);
Thing(3, string.Empty, null);
Thing(4, string.Empty, new Hello());
Thing(-69, "negative feeback", new Hello(), null);
Thing(42, "the meaning of life", new Hello(), new Hello());
Thing(666, theBeast.ToString(), new Hello(), new Hello(), new Hello());
// etc. etc.

根据您的评论,我认为您的问题实际上是,

为什么在使用参数名称时必须构造params数组?

这个问题是duplicate,但总而言之,因为它就是这样工作的。


如果您想省略s 并获得params 的好处,为什么不声明重载,

public void Thing(int x, string s = "", params Hello[] hellos)
{
}

public void Thing(int x, params Hello[] hellos)
{
    this.Thing(x, string.Empty, hellos);
}

那么您仍然可以按预期使用params,而无需使用参数名称。

此功能比可选参数更早,并且在很大程度上减轻了您的要求,我想这就是它从未得到解决的原因。

【讨论】:

  • 你是对的,但我想真正的问题是为什么他必须显式提供Hello 的数组,而不是在使用命名参数时传递多个Hello-objects
  • ...当操作使用参数名称时。
  • @Jodrell 是的,但如果可能的话,我想排除第二个参数和更技术性的解释。谢谢。
  • @Jodrell 总是有办法解决问题,例如超载,但我想深入了解它:)
【解决方案3】:

好吧,命名参数和params 有冲突的规则:命名参数可以以任何顺序出现,而params 必须在末尾。根据前者,我们应该可以这样做:

Thing(1, hello:new Hello(), new Hello(), s:string.Empty);

编译器当然可以计算出如何解释它,但是对于读者来说,它不像通常那样在末尾有参数那么清楚。但是如果 hello: 被强制放在最后,这将与命名参数不一致,并且会失去一些原本可以拥有的灵活性。

所以简而言之,我认为要求显式数组是一种妥协,可以保持最大的一致性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-10
    • 2016-03-27
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 2016-10-17
    • 1970-01-01
    相关资源
    最近更新 更多