如何确保使用'params'关键字的签名更改时出现编译错误

tyr*_*pex 8 c# params-keyword

我有这样的方法:

public void Foo(params string[] args) {
  bar(args[0]); 
  bar(args[1]);
}
Run Code Online (Sandbox Code Playgroud)

新要求会导致这样的变化:

public void Foo(string baz, params string[] args) {
  if("do bar".Equals(baz)) {
    bar(args[0]); 
    bar(args[1]);
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是即使我已经更改了方法签名,也没有发生编译错误,当然这是正确的,但是我希望每次调用没有指定Foo参数的方法时都会出现编译错误baz.也就是说,如果Foo在更改之前的呼叫是这样的:

Foo(p1,p2); //where p1 and p2 are strings
Run Code Online (Sandbox Code Playgroud)

它现在需要是这个:

Foo(baz,p1,p2);
Run Code Online (Sandbox Code Playgroud)

如果它不会以这种方式改变,p1则将被赋值给baz,并且params数组args的长度为1,并且OutOfBounds将抛出异常.

更改签名并确保所有调用代码都相应更新的最佳方法是什么?(真实场景是Foo许多项目共享的程序集中的生命自动构建在构建服务器上.编译错误因此是检测需要触及的所有代码以容纳更改的简单方法.)

编辑: 正如Daniel Mann和其他人指出的那样,上面的例子表明我根本不应该使用params.所以我应该解释一下,在我的真实世界的例子中,并不总是args需要有两个元素的情况,就Foo中的逻辑而言,args可以包含任意数量的元素.所以我们说这是Foo:

public void Foo(string baz, params string[] args) {
  if("do bar".Equals(baz)) {
    int x = GetANumberDynamically();
    for(int i = 0; i<x; i++)
      bar(args[i]); 
  }
}
Run Code Online (Sandbox Code Playgroud)

Ond*_*cek 3

这是解决方案。不要更改以前的方法签名,只需添加Obsolete指定了两个参数的属性。

[Obsolete("Use Foo(string, params string[]) version instead of this", true)]
public void Foo(params string[] args) {
  bar(args[0]); 
  bar(args[1]);
}
Run Code Online (Sandbox Code Playgroud)

然后使用新签名创建一个新方法。

public void Foo(string baz, params string[] args) {
  if("do bar".Equals(baz)) {
    bar(args[0]); 
    bar(args[1]);
  }
}
Run Code Online (Sandbox Code Playgroud)

属性中的第二个参数Obsolete可确保编译错误。如果没有它,它只会导致编译警告。有关该属性的更多信息可在MSDN上找到。

编辑:

根据下面评论中的讨论,丹尼尔·曼提出了一个有趣的问题。

那并不能解决问题。如果你调用 Foo("a", "b") 呢?在这种情况下,它仍然会调用仅带有两个参数的非过时方法,并导致相同的问题。

args我建议在调用之前检查是否有多个参数通过bar

  • 那并不能解决问题。如果你调用 `Foo("a", "b")` 会怎么样?在这种情况下,它仍然会调用仅带有两个参数的非过时方法,并导致相同的问题。 (2认同)