Is it possible to reference previous parameter as parameter default value in a C# method?

Viewed 164

I'm planning to write a C# extension method to only join a specific range of elements of a string array. For example, if I have this array:

+-----+  +-----+  +-------+  +------+  +------+  +-----+
| one |  | two |  | three |  | four |  | five |  | six |
+-----+  +-----+  +-------+  +------+  +------+  +-----+
   0        1         2          3         4        5

And I only want to join them using , from index 2 to index 4. I got three,four,five. If the user doesn't provide start index and end index, then my Join method will join all array elements. Below is my method signature.

public static class StringSplitterJoinner
{
    public static string Join(this string[] me, string separator, int start_index = 0, int end_index = me.Length - 1) {

    }
}

The problem is that the parameter end_index can't reference the first parameter me and it generates an error. I don't want the user to always provide start_index and end_index I want my method has some meaningful default values. In this case, how can I solve this problem?

3 Answers

I suggest using overloading:

public static string Join(this string[] me, string separator) {
  //TODO: add parameters' validation

  return Join(me, separator, 0, me.Length - 1);
}

public static string Join(this string[] me, string separator, int start_index) {
  //TODO: add parameters' validation

  return Join(me, separator, start_index, me.Length - 1);
}

public static string Join(this string[] me, string separator, int start_index, int end_Index) {
  //TODO: implement logic here
}

How about this:

public static class StringSplitterJoinner
{
    public static string Join(this string[] me, string separator, int start_index = 0, int? end_index = null)
    {
        if (!end_index.HasValue) end_index = me.Length - 1;
    }
}

You can also do this:

public static string Join<T>(this IReadOnlyCollection<T> me,
  string separator, int startIndex = 0, int endIndexInclusive = -1)
{
  if (endIndexInclusive < 0)
    endIndexInclusive += me.Count;

  var range = me.Skip(startIndex).Take(endIndexInclusive - startIndex + 1);
  return string.Join(separator, range);
}

The idea here is that negative indices count from the other end, so -1 is the last index, -2 is the second to last index, and so on. The value taken if the argument is not specified explicitly, -1, means the last entry in the collection.

(You could include if (startIndex < 0) startIndex += me.Count; as well if you wanted.)

Method has been made general (generic) but can still be used on a string[]. Example:

string[] myArray = ...
var joined = myArray.Join(",", 2, -3); // skips first two, and last two, entries

Be aware that the -3 can also be written as ~2 using bit-wise complement. That looks more symmetrical, myArray.Join(",", 2, ~2).

Related