简体   繁体   English

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

[英]Limit number of parameters per method?

Assuming the parameters are all the same type, is there a rule of thumb in regards to the number of parameters for a method? 假设参数类型相同,那么方法的参数数量是否有经验法则? Im just wondering where I should draw the line and what my alternatives are (ie interface, array, etc). 我只是想知道我应该在哪里绘制线和我的替代品(即接口,数组等)。

Steve McConnell addresses this in Code Complete , citing research that suggests people can't really handle more than seven chunks of information at a time, making seven a common-sense limit wherever it's practical. 史蒂夫麦康奈尔在Code Complete中解决了这一问题,理由是研究表明人们一次无法真正处理超过七个信息块,在任何实际情况下都会将七个信息作为常识限制。

In the concluding paragraph of that section (page 178 in the second edition), he writes: 在该节的结论段落(第二版第178页)中,他写道:

If you find yourself consistently passing more than a few arguments, the coupling among your routines is too tight ... If you are passing the same data to many different routines, group the routines into a class and treat the frequently used data as class data. 如果您发现自己一直传递多个参数,则例程之间的耦合太紧......如果您将相同的数据传递给许多不同的例程,请将例程分组到一个类中,并将常用数据视为类数据。

I would say it really depends on your case. 我会说这真的取决于你的情况。 Are you doing something to the entire set? 你在为整套做些什么吗? Validating all the items or aggregating data, for example? 例如,验证所有项目或聚合数据? In that case, I would pass in an IEnumerable as a single parameter. 在这种情况下,我会将IEnumerable作为单个参数传递。

Passing in a lot of parameters can be a good sign of poor separation of concerns (ie your method is doing too much), but it sounds like in this case you're passing in a well defined set of items to iterate them in some way. 传递大量参数可能是关注点分离不良的好兆头(即你的方法做得太多了),但听起来好像在这种情况下,你传递一组定义明确的项目以某种方式迭代它们。 Given the collection initializer syntax in C# 3, I would recommend IEnumerable in pretty much every case over a list of parameters that would be something like Type a, Type b, Type c... . 给定C#3中的集合初始化器语法,我会在几乎所有情况下推荐IEnumerable,这些参数列表类似于Type a, Type b, Type c...

Of course, if your parameters are actually treated differently, then separating them out makes sense, but I would consider what you're doing in that case. 当然,如果您的参数实际上被区别对待,那么将它们分开是有道理的,但我会考虑您在这种情况下正在做什么。 A simple case that comes to mind would be building a tree data structure and having a function to build up the children of a node. 想到一个简单的案例就是构建树数据结构并具有构建节点子节点的功能。 A poor syntax might be: 语法不佳可能是:

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

I would probably pursue something more like: 我可能会追求更像:

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

If you can provide more information about your case, though, and what sort of logic you're performing on the parameters, it would probably be easier to see if it's a good candidate for collapsing or refactoring. 但是,如果您可以提供有关您的案例的更多信息,以及您对参数执行的逻辑类型,则可能更容易看出它是否是折叠或重构的良好候选者。

I try to limit it to 4 or so. 我试着把它限制在4左右。 Some people say less, some say more. 有人说少说,有些人说更多。

The alternative to tons of parameters would be to create an operation class, ie replace: 大量参数的替代方法是创建一个操作类,即替换:

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

with

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

This has a few advantages over the function: 这比功能有一些优点:

  • If some parameters are optional, you can expose them as properties (such as pizza above). 如果某些参数是可选的,您可以将它们公开为属性(例如上面的pizza )。
  • If your function takes that many arguments, chances are it does a lot, and could be broken into smaller functions. 如果你的函数接受了那么多参数,那么很可能它会做很多事情,并且可以分解成更小的函数。 A class helps you do this cleanly. 一堂课帮助你干净利落地完成这项工作。

If you will be passing an unknown number of arguments, you should use varargs or pass a IEnumerable. 如果您要传递未知数量的参数,则应使用varargs或传递IEnumerable。 Of course, sometimes you pass a fixed number of items of the same type. 当然,有时您会传递相同类型的固定数量的项目。 In the latter case, the fixed number should follow from the method's purpose. 在后一种情况下,固定数字应该遵循方法的目的。

Also, for greater call-site readability, you could use a params parameter list (the varargs mentioned before), so instead of 此外,为了获得更好的呼叫站点可读性,您可以使用params参数列表(之前提到的varargs),而不是

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

I would use 我会用

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

However, the params syntax gets ugly to look at if you use more that 5-6-7 items in the children collection. 但是,如果在子集合中使用更多5-6-7个项目,则params语法会变得难看。

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

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