Question

I realize this is a pretty open question and could get a variety of answers, but here goes.

Using C# (or Java, or any OO language), is there a general rule that states how many variables should be passed into the constructor? The number of variables I am passing into the constructor of the extended classes seem to be getting out of hand.

In an effort to encapsulate the data of a class, I declare the members private, initialize them in my constructor, and use public accessors.

Here is an example:

public class A
{
  private int var1;
  private int var2;
  private int var3;

  //3 variables passed in
  public A(int v1, int v2, int v3)
  {
    var1 = v1;
    var2 = v2;
    var3 = v3;
  }

  //Properties (accessors) here
}

public class B : A
{
  private int var4;
  private int var5;

  //5 variables passed in
  public B(int v1, int v2, int v3, int v4, int v5)
  : base(v1,v2,v3)
  {
    var4 = v4;
    var5 = v5;
  }

  //Properties (accessors) here
}

public class C : B
{
  private int var6;
  private int var7;

  //7 variables passed in !!!
  public C(int v1, int v2, int v3, int v4, int v5, int v6, int v7)
  : base(v1,v2,v3,v4,v5)
  {
    var6 = v6;
    var7 = v7;
  }

  //Properties (accessors) here
}

My constructors are usually passing in different objects, not just ints. I started questioning my design when I started passing in 7 variables to the constructor of the child class, but I have also had trouble figuring out a different way to do this.

Is this considered bad programming practice? Is there a general limit to the number of variables you should pass into a constructor?

Was it helpful?

Solution

Generally I've found if there's more than 3, that's a sign to do a quick sanity check on the design. If there's more than 5, that's a major warning that something is probably wrong with the design.

However, note the word "probably" - in the end, the only real rule is use as many as needed to function, no more and no less. There are always exceptions and cases where more parameters makes the most sense.

If the parameters are related somehow, you should encapsulate them into a container class.

If the parameters are not related - e.g. it makes no sense to group them into a container class - your class is probably doing too many things. There's generally no reason a single class should be aware of 7 totally disparate pieces of information. Break your class apart into separate classes. It might make sense to delegate parameters 3 and 4 to a subclass and 5, 6 and 7 to another class for example - and your parent class simply coordinates the operations between them.

OTHER TIPS

For me, the correct answer is:

You should pass in as many variables as is required to setup the object in a state that is not invalid.

Anything else that is "option", I prefer to leave as properties, especially now that C# provides object initializers.

Its difficult to put a hard, fast number to what is "too much". The real question is this: What is your class doing? Is the class doing too much? If so, it is time to break the class into smaller, more concise classes.

Constructor parameters should include as many as necessary to define the dependencies/inputs for the class. If the class is reduced to have one job in life, then your constructor parameters will probably be correct.

As others have said, there is no hard rule on this, it really depends. However, there is concrete evidence as to how many things a person's brain can grasp at once: that's the 7 + or - 2 rule.

This type of question is very well answered in Code Complete by Steve McConnell. I recommend you read this book if you haven't already.

One thing I love about the 3.5 framework...

new Foo {
    Street = "909 Rose Ave",
    City = "San Diego",
    State = "CA",
    FName = "Joe",
    LName = "Wazowski",
    ID = "987665454"
};

No more worrying about too many constructors, or too many constructors with too many parameters.

My personal rule of thumb is 5

If you need more, wrap them in a structure or object.

This changes when you do not have to initialize the object. If I initialize an object using a IOC container the number of constructure parameters are basically unlimited.

Especially since the newer features that allow you to set variables in a block with the instantiation, I tend to only use parameters on creation for things that HAVE to be set when the class is created, in which case I make the basic constructor private or protected.

For example, if you had a class Rectangle, it might make sense to make the constructor Rectangle(double width, double height), and make the Rectangle() constructor private.

Also, you might put a parameterless private constructor, if you believe that your class should only set it's properties values through the constructor.

A system has too many parameters as soon as it becomes hard to remember how to use them. If they are all ints, 3 is too many. If they are different types you can have more.

This is a smell in Martin Fowler's Refactoring book. This web page contains links to standard refactorings that help.

In your case, you might want to consider a builder object (where you can gradually add the parameters and the builder figures out the class) or a parameter object.

IMHO, using TDD is a helpful perspective to evaluate this problem. Once your ctor is hard to apply to the unit test ctor or SetUp(), the arguments of initialization/factory are too many and relatively too tightly coupled.

You need to pass in everything required to construct the class. What i often do when i find myself passing in a lot of variables is make a "Configuration" class for the object that holds the information needed to construct the it, passing that to the constructor. It greatly simplies instantiating objects and makes for a cleaner design.

I will try to answer this question from a different perspective. I see two major ways of using the constructors, so two way of thinking about how many parameters is too many.

1) Explicitly called constructors

This is the classic approach where you "new" your objects and you must specify all the mandatory parameter values. This was fully covered by other answers here. My personal rule of thumb is: all parameters should fit on one line, so I will have maximum of 3-4 parameters.

Also, if you know that you class is likely to be able to handle more cases that require more parameters in the future, I would go with a struct/class directly. E.g.:

let's say a class should handle some objects filtering based on some criteria. At the beginning, there will only 2-3 criteria. Knowing that it is likely to have much more criteria in the future, I would directly send a FilterValue object from the beginning.

2) Implicitly called constructors

A typical case is using Dependency Injection. In almost all cases, all constructor parameters are injected, so it is the DI framework's business to build the objects for you.

Here, the "common sense" does not apply, as one may inject as many services as needed. E.g.:

If data persistence is performed using an Unit of Work pattern that aggregates changes from any number of repositories, than Unit of work class will be injected with all used repositories. More details can be found within this answer from CodeReview.

By the way, the maximum theoretical number of parameters for a method should be high enough not to ever reach it: C# and Java.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top