ChadF
ChadF

Reputation: 1758

Optional Argument in C#, reference other argument

I'm trying to write a recursive function in C# that will take two arguments, an Array, and an index. The index should change on each recursion, but start being the length of the Array - 1.

Like this:

public static int[] UpArray(int[] num, int i = num.Length - 1) {...}

However, I cannot reference num. I could pass along a boolean stating whether this is the first time through or not and include an if-clause in the code. But I was wondering if there was a more elegant way.

Upvotes: 0

Views: 120

Answers (3)

Onkelborg
Onkelborg

Reputation: 3997

I would suggest an anonymous method:

public static int[] UpArray(int[] num) {
  Func<int[], int> f = null;
  f = (int[] num, int i) => {
    //Do something and then something like:
    f(num, num.Length - 1);
  };
  f(num, num.Length);
}

The benefit of this approach is that the only method you are able to call is the outer one; the inner, anonymous, method isn't possible to call. It's clean and is not polluting the namespace. When you are about to call the method there is only one method, and no risk of invoking the wrong method (or just trying to figure out which method to call.)

Upvotes: 1

David
David

Reputation: 10708

It may be more elegant to use an overload which doesn't require an index. This will also allow the function to be used as a method group when needed in place of a lambda, since lambdas can't utilize the optional parameters' defaults

public static int[] UpArray(int[] num) { return UpArray(num, num.Length - 1); }
public static int[] UpArray(int[] num, int index)
{
    //...
}

this also allows you to hide the inner function if you want to force implementation to use always start at the end:

public static int[] UpArray(int[] num) //...
private static int[] UpArray(int[] num, int index) //...

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500105

No, the default value for an optional parameter has to be a constant.

You could use -1 as the default value as suggested in comments, or make it a nullable int and default it to null:

public static int[] UpArray(int[] num, int? index = null)
{
    int realIndex = index ?? num.Length - 1;
    ...
}

Or better yet, just have two methods:

public static int[] UpArray(int[] num)
{
    return UpArray(num, num.Length - 1);
}

private static int[] UpArray(int[] num, int index)
{
    ...
}

That's assuming you don't want the external caller to actually specify the index - you just want to do that on the recursive calls.

No need for any optional parameters, and the overall API is what you really want, rather than it letting implementation details peek through.

Upvotes: 9

Related Questions