【发布时间】:2013-12-05 13:00:03
【问题描述】:
我有这样的方法:
public void Foo(params string[] args) {
bar(args[0]);
bar(args[1]);
}
新的要求导致了这样的变化:
public void Foo(string baz, params string[] args) {
if("do bar".Equals(baz)) {
bar(args[0]);
bar(args[1]);
}
}
问题是,即使我更改了方法签名,也没有发生编译错误,这当然是正确的,但我希望每次调用 Foo 方法时都会出现编译错误,其中参数 baz尚未指定。也就是说,如果在更改之前对 Foo 的调用是这样的:
Foo(p1,p2); //where p1 and p2 are strings
现在必须是这个:
Foo(baz,p1,p2);
如果不以这种方式更改,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]);
}
}
【问题讨论】:
-
为什么不改变签名来做一些完全不同的事情(比如使用
int或其他东西)。那么所有方法都会抛出编译错误?当然,更好的方法是使用 Resharper 或类似工具进行重构。 -
添加到@dav_i:如果您首先添加
int而不是string,编译,修改所有调用代码,然后将int更改为string。另请注意,if("do bar".Equals(baz)) {是一个非常糟糕的示例,听起来需要再次重载或进行更多重构。 -
按照@OndrejJanacek 的建议去做。这是绝对最好的方法。
-
只是为了确定:您的参数参数是否需要两个输入或至少两个输入?在前一种情况下,我建议根本不使用参数...
-
@dav_i 我不喜欢这样的原因是依赖项目的维护分散在不同的人身上。如果由于签名中的 int 而突然在他们的表上出现构建错误,这可能会令人困惑并且不明显他们需要做什么。我想要的是一个需要修复的编译错误,这是永久解决方案。但如果这无法实现,我想我会接受你的建议。
标签: c# params-keyword