我有这样的方法:
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)
这是解决方案。不要更改以前的方法签名,只需添加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
。