限制每种方法的参数数量?

时间:2010-06-03 12:43:40

标签: c# design-patterns parameters

假设参数类型相同,那么方法的参数数量是否有经验法则?我只是想知道我应该在哪里绘制线条以及我的替代品(即界面,数组等)。

5 个答案:

答案 0 :(得分:9)

史蒂夫麦康奈尔在Code Complete中提到这一点,理由是研究表明,人们不能真正处理七个以上的信息块,在任何可行的地方都有七个常识限制。

在该部分的结论段落(第二版第178页)中,他写道:

  

如果你发现自己一贯   通过了几个论点,   您的惯例之间的耦合也是如此   紧...如果你传球一样   数据到许多不同的例程,组   将惯例变成一个阶级并对待   经常使用的数据作为类   数据

答案 1 :(得分:7)

我会说这真的取决于你的情况。你在为整套做些什么吗?例如,验证所有项目或聚合数据?在这种情况下,我会将IEnumerable作为单个参数传递。

传递很多参数可能是关注点分离不良的一个好兆头(即你的方法做得太多了),但听起来好像在这种情况下你传递了一组定义良好的项目来迭代它们某种程度上来说。鉴于C#3中的集合初始化器语法,我会在几乎所有情况下推荐IEnumerable,而不是像Type a, Type b, Type c...这样的参数列表。

当然,如果您的参数实际上被区别对待,那么将它们分开是有意义的,但我会考虑您在这种情况下正在做什么。想到一个简单的案例就是构建树数据结构并具有构建节点子节点的功能。语法不佳可能是:

Node BuildTree( Node parent, Node child1, Node child2...)

我可能会追求更像:

void ConstructChildren( this Node parent, IEnumerable<Node> children)

如果您可以提供有关您的案例的更多信息,以及您对参数执行的逻辑,那么可能更容易看出它是否适合折叠或重构。

答案 2 :(得分:3)

我尝试将其限制为4左右。有些人说少,有些人说更多。

大量参数的替代方法是创建一个操作类,即替换:

func(boo, far, lint, pizza, flags);

var action = new DoSomethingObject(boo, far, lint);
action.Food = pizza;
action.Go(flags);

这比函数有一些优点:

  • 如果某些参数是可选的,您可以将它们公开为属性(例如上面的pizza)。
  • 如果你的函数接受了那么多的参数,很可能它会做很多,并且可以分解成更小的函数。一堂课可以帮助你干净利落。

答案 3 :(得分:2)

如果您要传递未知数量的参数,则应使用varargs或传递IEnumerable。当然,有时您会传递相同类型的固定数量的项目。在后一种情况下,固定数字应该遵循方法的目的。

答案 4 :(得分:1)

此外,为了获得更好的呼叫站点可读性,您可以使用params参数列表(之前提到的varargs),而不是

void ConstructChildren( Node parent, IEnumerable<Node> children)
....
List<Node> children = new List<Node> {child1, child2, child3};
ConstructChildren(parent, children);

我会用

void ConstructChildren( Node parent, params Node[] children)
...
ConstructChildren( parent, child1, child2, child3);

但是,如果在子集合中使用更多5-6-7个项目,则params语法会变得难看。