开发者

Limit number of parameters per method?

开发者 https://www.devze.com 2023-01-01 21:35 出处:网络
Assuming the parameters are all the same type, is there a rule of thumb in regards to the number of para开发者_运维知识库meters for a method?Im just wondering where I should draw the line and what my

Assuming the parameters are all the same type, is there a rule of thumb in regards to the number of para开发者_运维知识库meters 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.

In the concluding paragraph of that section (page 178 in the second edition), he writes:

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.

Passing in a lot of parameters can be a good sign of poor separation of concerns (i.e. 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....

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. Some people say less, some say more.

The alternative to tons of parameters would be to create an operation class, i.e. 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).
  • 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. 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

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消