stardotstar
stardotstar

Reputation: 318

C# - setting a default value for an out parameter of a delegate action

protected IteratorAdvance<int> Advance;

public delegate void IteratorAdvance<T2>(out T2 itemIndex);

public IteratorBase()
{
   Advance = delegate(out int i) { i++; };   // <--- here
}

Above is a snippet of a class that is a wrapper for a number of types of loop. In the constructor overload below, the instantiator can specify the method by which the condition of continuing a for loop is determined and also how the control value of that loop is modified on each iteration.

Obviously, the simplest and most likely use of this is to start at 0 and increment by 1 until the last index of the data source is reached. To that end I've provided default methods and an initial value that are effectively (and in this case a very convoluted version of)

for(var i = 0; i < list.Count; i++)

Here's the constructor:

public IteratorBase(IterationStyle style, Func<int, T1, bool> complete, IteratorAdvance<int> advance,  bool onErrorAbort = true, int initialValue = 0)
{
    Style = style;
    InitialValue = initialValue;
    Complete = complete;
    Advance = advance;
    AbortOnError = onErrorAbort;
}

The problem is where I'm incrementing the control value, the compiler wants a default value for a variable (i) that is declared in that scope and because it is an out parameter, cannot accept a default value.

Even if I move the body of the function to a separate method, the same problem exists. I cannot initialise the out parameter prior to the for loop itself initialising it.

case IterationStyle.For:
     for (controlValue = InitialValue; !Complete(controlValue, item); Advance(out controlValue))
     {
         action.TargetItem = item = dataSource[controlValue];
         if (!ActWrapper(action))
             return false;
     }
     break;

The only solution I can think of is to intialise the out parameter only on the first call of the method, which will involve using some kind of boolean external to the method. I don't think I'm alone in preferring to avoid that sort of thing. And it turns out it that doesn't work either so I would have to make the control value global. Over my dead body.

Usually, in this sort of situation it means your approach is wrong. But I can't think of another way. I'm hoping you can. Or else tell me how I can either initialise an out parameter or give it a default value.

Upvotes: 0

Views: 730

Answers (1)

stardotstar
stardotstar

Reputation: 318

Just in case anyone else is having a bad brain day, here's the solution. Use ref not out.

 Advance = delegate(ref int i) { i++; };

Upvotes: 2

Related Questions