-1

I have some loops inside of each other. In the most inner loop I calculate values that will be needed outside of the loops later.

public class Foo
{
    public void Bar()
    {
        ...
        double baz;
        var i = 0;
        while (i < 100)
        {
            ...
            var j = 0;
            while (j < 100)
            {
                ...
                baz = DoSomething(i, j);
                
                j++;
            }

            i++;
        }

        // some more calculations. helper1 and helper2 with only the
        // the last values of i and j are needed and I do not want
        // to calculate them again
    }

    private double DoSomething(int i, int j)
        {
            // many lines of code with complex calculations
            var helper1 = i + j;
            var helper2 = 2*i + j;
            baz = helper1 + helper2;
            return baz;
        }
}

Option 1: I could calculate helper1 and helper2 again but this is time consuming and not necessary.

Option 2: I could pass out the values with out.

Option 3: I could create a static class with static properties where I store the values in. Inside Loop 2: StaticClass.MoreValues1 = bar;...

All three options do not seem good practice to me. Is there a better way?

Many thanks

Edit: Updated code block for clarification.

Edit: Added dependency of i and j to helper1 and helper2

Flippowitsch
  • 315
  • 3
  • 15
  • This would have been 10 times easier to understand with actual code. However, out params, return values, delegates, shared class members, static class, they are all syntactically valid choices. However a return value seems the most straightforward and sane. – TheGeneral Sep 06 '21 at 06:50
  • Though without know "*exact*" specifics of what you trying to do or how, its hard to give any advice at all – TheGeneral Sep 06 '21 at 06:57
  • Thanks for your feedback and answers. I updated the code block for clarification. – Flippowitsch Sep 06 '21 at 07:40
  • 2
    After the edit: Now, that makes me wonder why you calculate `helper1` and `helper2` inside of `DoSomething()`? What do they depend on? If they keep their values across all calls to DoSomething _and_ their calculation is non-trivial, they should not be calculated there. But: they seem to have to be different for each call, otherwise, the loops don't make sense. You'd only ever need one single call because the sum would be the same, always. Which also means: a single set of `helperN` to use afterwards doesn't make sense, neither. (Except you only need the _last_ values of those.) – Fildor Sep 06 '21 at 07:41
  • Option 4: don't return (just) one `double`, but some extra (non-static) class that contains all calculation results that you need – Hans Kesting Sep 06 '21 at 07:46
  • @HansKesting That's what I have been suggesting before the edit, basically (comment and answer deleted, since). But there are some contradictions in the logic here, that I cannot make sense of. So it is hard to tell if this question may be x-y. – Fildor Sep 06 '21 at 07:49
  • 1
    @Fildor: You are absolutely right: The helpers are different for each call. I only need the last values. I edited the question accordingly. – Flippowitsch Sep 06 '21 at 07:57
  • OK, so what you want to end up with is "all the bazz's and the last values of helper1 and helper2". Is that correct? – Fildor Sep 06 '21 at 08:01
  • 1
    Even also only the last baz. – Flippowitsch Sep 06 '21 at 08:11

1 Answers1

1

Based on the edits and comments:

  • "The helpers are different for each call. I only need the last values."
  • "Even also only the last baz."

I'd refactor like so:

public class Foo
{
    public void Bar()
    {
        ...
        double lastBaz;
        int helper1;
        int helper2;
        var i = 0;
        while (i < 100)
        {
            ...
            var j = 0;
            while (j < 100)
            {
                ...
                lastBaz = DoSomething(i, j, out helper1, out helper2);
                j++;
            }
            i++;
        }

        // some more calculations. helper1 and helper2 with only the
        // the last values of i and j are needed and I do not want
        // to calculate them again
    }

    private double DoSomething(int i, int j, out int helper1, out int helper2)
    {
            // many lines of code with complex calculations
            helper1 = i + j;
            helper2 = 2*i + j;
            baz = helper1 + helper2;
            return baz;
     }
     
}

That would be for a first step. I'd probably look over this again to see if I can tweak it to be more efficient (memory/exec time) and readable.

Probably, I'd switch to a struct to return all three values instead of using out params.

public class Foo
{
    public void Bar()
    {
        ...
        BazResult lastResult;
        var i = 0;
        while (i < 100)
        {
            ...
            var j = 0;
            while (j < 100)
            {
                ...
                lastResultz = DoSomething(i, j);
                j++;
            }
            i++;
        }

        // some more calculations. helper1 and helper2 with only the
        // the last values of i and j are needed and I do not want
        // to calculate them again
        
        // use lastResult.Baz
        // use lastResult.Helper1
        // use lastResult.Helper2
    }

    private BazResult DoSomething(int i, int j)
    {
            // many lines of code with complex calculations
            helper1 = i + j;
            helper2 = 2*i + j;
            baz = helper1 + helper2;
            return new BazResult(baz, helper1, helper2);
     }
     
}


public struct BazResult
{
    public readonly double Baz;
    public readonly int Helper1;
    public readonly int Helper2;
    
    public BazResult(double baz, int h1, int h2)
    {
        Baz = baz; 
        Helper1 = h1; 
        Helper2 = h2;
    }
}
Fildor
  • 14,510
  • 4
  • 35
  • 67
  • Thanks! I found [this](https://stackoverflow.com/questions/43278063/returning-multiple-value-with-the-out-keyword-in-c-sharp) about `out` and therefore think `struct` is a good solution. Or what do you think about properties Helper1 and Helper2 within class Foo (= Option 4)? – Flippowitsch Sep 06 '21 at 08:30
  • HelperN as properties to class Foo could lead to unwanted sideeffects and problems with thread-safety. I'd keep them local, so you don't have to care about this too much. – Fildor Sep 06 '21 at 08:33
  • About prefering something other than `out` - yes. I personally have _very_ rare use for them (same goes for `ref`). And I prefer to not use them. For people coming from C they'd make a more familiar API, but well, ... they do come with quirks. But "the right tool for every problem" - they have their place. This is probably not for them, exactly. – Fildor Sep 06 '21 at 08:36
  • Aren't HelperN local when they are private? Or do I misunderstand something? – Flippowitsch Sep 06 '21 at 08:38
  • 1
    Local to the method, I meant. If they are properties on the class, every call the method on the same instance will mutate them. If you do that on two threads, you'll get funny bahavior. – Fildor Sep 06 '21 at 08:40