繁体   English   中英

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

[英]Limit number of parameters per method?

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

史蒂夫麦康奈尔在Code Complete中解决了这一问题,理由是研究表明人们一次无法真正处理超过七个信息块,在任何实际情况下都会将七个信息作为常识限制。

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

如果您发现自己一直传递多个参数,则例程之间的耦合太紧......如果您将相同的数据传递给许多不同的例程,请将例程分组到一个类中,并将常用数据视为类数据。

我会说这真的取决于你的情况。 你在为整套做些什么吗? 例如,验证所有项目或聚合数据? 在这种情况下,我会将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)

但是,如果您可以提供有关您的案例的更多信息,以及您对参数执行的逻辑类型,则可能更容易看出它是否是折叠或重构的良好候选者。

我试着把它限制在4左右。 有人说少说,有些人说更多。

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

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

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

这比功能有一些优点:

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

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

此外,为了获得更好的呼叫站点可读性,您可以使用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语法会变得难看。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM