To start with I\'ll say that I agree that goto statements are largely made irrelevant by higher level constructs in modern programming languages and shouldn\'t be used when
You can certainly create a goto solution in C# (note: I didn't add null checks):
string Join(string[] array, string delimiter) {
var sb = new StringBuilder();
var enumerator = array.GetEnumerator();
if (enumerator.MoveNext()) {
goto start;
loop:
sb.Append(delimiter);
start: sb.Append(enumerator.Current);
if (enumerator.MoveNext()) goto loop;
}
return sb.ToString();
}
For your specific example, this looks pretty straighforward to me (and it's one of the solutions you described):
string Join(string[] array, string delimiter) {
var sb = new StringBuilder();
foreach (string element in array) {
sb.Append(element);
sb.Append(delimiter);
}
if (sb.Length >= delimiter.Length) sb.Length -= delimiter.Length;
return sb.ToString();
}
If you want to get functional, you can try using this folding approach:
string Join(string[] array, string delimiter) {
return array.Aggregate((left, right) => left + delimiter + right);
}
Although it reads really nice, it's not using a StringBuilder, so you might want to abuse Aggregate a little to use it:
string Join(string[] array, string delimiter) {
var sb = new StringBuilder();
array.Aggregate((left, right) => {
sb.Append(left).Append(delimiter).Append(right);
return "";
});
return sb.ToString();
}
Or you can use this (borrowing the idea from other answers here):
string Join(string[] array, string delimiter) {
return array.
Skip(1).
Aggregate(new StringBuilder(array.FirstOrDefault()),
(acc, s) => acc.Append(delimiter).Append(s)).
ToString();
}