Multiple return statements smells like what? Here's some code of mine that I don't like (this was my very first attempt at DI/IoC!). It's a small C# application that runs scheduled on one of our servers and is responsible for fetching the latest version of a VB6 codebase, compiling it and packaging an installer for it.

There's an Execute method in there that smells like... well you tell me what it smells like:

    /// &lt;summary&gt;
    /// Executes the build process.
    /// &lt;/summary&gt;
    public override void Execute()
    {
        var errors = new List&lt;string&gt;();
        var logger = _logProvider.GetLogger(GetType().Name);

        DoArchiveOldInstallers(errors, logger);
        if (Properties.Settings.Default.StopOnBackupCurrentInstallerFailure &amp;&amp; !DoBackupCurrentVersion(errors, logger))
        {
            OnExecutedCompleted(false);
            return;
        }

        if (Properties.Settings.Default.StopOnUpdateCodeBaseFailure &amp;&amp; !DoGetLatestVersion(errors, logger))
        {
            OnExecutedCompleted(false);
            return;
        }

        if (Properties.Settings.Default.StopOnCompileFailure &amp;&amp; !DoCompileCodeBase(errors, logger))
        {
            OnExecutedCompleted(false);
            return;
        }

        if (Properties.Settings.Default.StopOnBuildInstallerFailure &amp;&amp; !DoBuildInstaller(errors, logger))
        {
            OnExecutedCompleted(false);
            return;
        }

        OnExecutedCompleted(true);
    }

    private void OnExecutedCompleted(bool success)
    {
        if (Completed != null) Completed(this, new CompletedEventArgs(success));
    }




Mea Culpa

Sorry this was posted like this. The conditions should read as follows:

if (!DoXXXXX(errors, logger) &amp;&amp; !settings.StopOnXXXXXFailure)


This was a last-minute untested change I made just minutes prior to posting, without realizing it would totally mess up the method's logic.
First of all, I would question whether this code works correctly. Based on the names in your code, I assume that for example DoCompileCodeBase() should execute even when StopOnCompileFailure is false, but its result should be ignored. But that's not what happens: when StopOnCompileFailure is false, DoCompileCodeBase() doesn't even execute, because of short-circuiting evaluation of &amp;&amp;.

If what the code does is really what it should do (which is what I'm going to assume in the following text), then you should probably rename the settings properties.

Second, you can extract the checks and the Do method calls into a separate method (Simon's answer already suggested something similar):

// may need a better name
private bool ExecuteInternal()
{
    var errors = new List&lt;string&gt;();
    var logger = _logProvider.GetLogger(GetType().Name);
    var settings = Properties.Settings.Default;

    DoArchiveOldInstallers(errors, logger);

    if (settings.StopOnBackupCurrentInstallerFailure &amp;&amp; !DoBackupCurrentVersion(errors, logger))
        return false;

    if (settings.StopOnUpdateCodeBaseFailure &amp;&amp; !DoGetLatestVersion(errors, logger))
        return false;

    if (settings.StopOnCompileFailure &amp;&amp; !DoCompileCodeBase(errors, logger))
        return false;

    if (settings.StopOnBuildInstallerFailure &amp;&amp; !DoBuildInstaller(errors, logger))
        return false;

    return true;
}

public override void Execute()
{
    bool success = ExecuteInternal();
    OnExecutedCompleted(success);
}


Third, since all the Do methods are on the same object, you could change errors and logger into fields, so that you don't have to pass them around. Though I'm not completely convinced this is actually better, especially if Execute() is a method that's called over and over.

Fourth, you might consider associating all the settings properties with the right Do method using some kind of data structure:

private readonly Tuple&lt;bool, Func&lt;bool&gt;&gt;[] action;

// in constructor:
actions = new Tuple&lt;bool, Func&lt;bool&gt;&gt;[]
{
    new Tuple&lt;bool, Func&lt;bool&gt;&gt;(settings.StopOnBackupCurrentInstallerFailure, DoBackupCurrentVersion),
    new Tuple&lt;bool, Func&lt;bool&gt;&gt;(settings.StopOnUpdateCodeBaseFailure, DoGetLatestVersion),
    new Tuple&lt;bool, Func&lt;bool&gt;&gt;(settings.StopOnCompileFailure, DoCompileCodeBase),
    new Tuple&lt;bool, Func&lt;bool&gt;&gt;(settings.StopOnBuildInstallerFailure, DoBuildInstaller)
}

private bool ExecuteInternal()
{
    var errors = new List&lt;string&gt;();
    var logger = _logProvider.GetLogger(GetType().Name);
    var settings = Properties.Settings.Default;

    DoArchiveOldInstallers();

    foreach (var action in actions)
    {
        if (action.Item1 &amp;&amp; !action.Item2())
            return false;
    }

    return true;
}


The syntax to initialize the list of Tuples is not great. You could improve that by having a special type TupleList&lt;T1, T2&gt; : List&lt;Tuple&lt;T1, T2&gt;&gt;, which would have a method like void Add(T1 item1, T2 item2). That way, the initialization simplifies to:

actions = new TupleList&lt;bool, Func&lt;bool&gt;&gt;
{
    { settings.StopOnBackupCurrentInstallerFailure, DoBackupCurrentVersion },
    { settings.StopOnUpdateCodeBaseFailure, DoGetLatestVersion },
    { settings.StopOnCompileFailure, DoCompileCodeBase },
    { settings.StopOnBuildInstallerFailure, DoBuildInstaller }
}


The next step after this could be encapsulating each action into its own object, so that you could do something like:

foreach (var action in actions)
{
    if (!action.Execute())
        return false;
}


And each action would be responsible for checking the right setting, if appropriate. (Actions that don't do any checks, like DoArchiveOldInstallers could be represented by a different type that inherits from the same base, or something like that.) But I'm not sure doing that would be worth it in this case.