4

Considering I have a for loop in a method of a class. Should the incremented variable be declared as member of the class, or should it be declared in the method it uses it(or even in the for loop, directly)? While declaring it inside the method seems easier and cleaner, doesn't declaring it at the start of the class makes you have more control over it? Something like declaring it int var_used_for_loop_in_method_x. What is good programming practice?

Note that I'm not asking specifically for the for loop. I am asking if we should try to put most variables as class members as much as possible or not.

3

1 Answer 1

45

Rule of thumb: variables should always be in - or as close as possible to - the scope where they are needed. Another way to phrase it is that variables should be enclosed inside the context in which they make sense and are actually useful.

Most often you will want to declare your incrementing variable along with the for statement. Sometimes you will declare it a bit higher in the hierarchy because you need to know how many occurrences you looped through or at which point the loop was interrupted.

In almost all scenarios, having a loop increment variable declared as a class field is a bad idea. It won't give you any kind of additional "control"; if anything, it will only pollute your class and make it harder to figure out from an outsider's perspective. Plus, if you inadvertently use it in more than one loop, it may even break your code.

UPDATE:

About the latter, as keshlam explains very well in the comments below, a smaller scope will minimize the risk of your variable being modified where you wouldn't expect it. Plus, as he further explains, variables can safely free up used memory when going out of scope. Most modern languages will even do that for you automatically (your mileage may vary).

Also, since you asked what purpose could class-level variables serve, here are two examples in :

Property backends

This is likely the most popular use-case.

public class ConnectionHolder
{
    // ...

    IDbConnection _connection;

    public IDbConnection Connection
    {
        get { return _connection; }
    }

    // ...
}

Holder of instance state information

Here we have the property in the above example accessing a factory that will in turn produce an instance of a IDbConnection. The _connectionAccessed boolean variable serves as a flag to tell if an attempt at getting ahold of a connection already has been made.

public class ConnectionHolder
{
    // ...

    bool _connectionAccessed = false;
    IDbConnection _connection;

    public IDbConnection Connection
    {
        get
        {
            if (!_connectionAccessed)
            {
                _connectionAccessed = true;
                _connection = ConnectionFactory.Create();
            }

            return _connection;
        }
    }

    // ...
}

As you can see in the two examples above it makes complete sense for the variables to be declared within full class scope.

I hope you find this information useful.

6
  • 17
    To advance on this: variables should have the smallest possible scope that gets the job done. That's why index variables are declared in the for loop. It is also related to the rule of thumb: initialize things as late as possible. By implication then, since you want to have variables initialized, they should be declared as late as possible. Commented Mar 25, 2014 at 22:17
  • 7
    Implied but not explicitly stated in the above: The reason for the smaller scope is that it reduces the risk of unintentional "crosstalk" between sections of the code that reuse a shared variable. (An old value being carried over if you forget to re-initialize it, for example.) It also may encourage better heap discipline, releasing/freeing objects as soon as they're no longer needed. But note that not all languages will permit you to scope a variable more narrowly than to a function... which becomes another good reason to keep methods from getting too large.
    – keshlam
    Commented Mar 26, 2014 at 2:53
  • Then what's the purpose of class member variables if all variables can be declared in each method? Commented Mar 26, 2014 at 5:26
  • 1
    Keeping declarations close during initial development can also be helpful later when refactoring and looking for methods/classes to extract. In other words, if you keep your declarations and usages close, and find a large method/class that looks like lots of smaller groups (that may only be related relative to the context of the containing method/class), then it's likely they should (or at least can) be broken-out into other methods/objects with relative ease.
    – derGral
    Commented Mar 26, 2014 at 5:32
  • 1
    Data that's relative to the object as a whole is stored as a member variable. For example, a person object would probably have a name, date of birth, or whatever. Because they're about the object. The index of a for-loop is operation specific and so is defined and used only where that operation takes place. This gets in to a larger topic about what should get passed into a method (public, private, or otherwise) to ensure that the method is 'atomic' (or whatever you want to call "wont trip over itself" in multi-threaded environments).
    – derGral
    Commented Mar 26, 2014 at 5:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.