There are three easy ways to do this:
First method:
//use a struct to wrap values:
struct returnPair { public int number; public int[] array; }
private returnPair MyFunction(int arg1) {
return new returnPair { number = ...., array = ...., };
}
Prefer struct to class because it is passed by value and thus avoids some mutability issues, and also avoids dealing with null. Prefer fields to properties because fields are shorter to declare and have no downside in this use-case.
Second method:
Use a tuple via Tuple.Create(....,....)
- this is explained in other answers.
Third method:
Use a continuation/callback. Don't overdo it; but sometimes this is a good alternative; particularly when you want to "return" multiple items but can't easily use the yield return
strategy, such as when dealing with heavily recursive functions, or enumerating more than once isn't supported. It also has the advantage of permitting quite readable calls - better than tuples in C#.
private void MyFunction(int arg1, Action<int, int[]> yieldF) {
yieldF(....num, ....arr);
yieldF(....num2, ....arr2); //and again...
}
//call like this note that unlike a tuple params are labelled and readable,
//basically like a foreach loop with multiple loop variables:
MyFunction(3+4+5, (intp, arrp) => {
Do-My-Side-Effect
});
Sneaky Method :-)
If you're sneaky (not recommended) you can even combine the first and third options and abuse type-inference to get named parameters wrapped in an auto-generated readonly class :-)
private T MyFunction<T>(int arg1, Func<int, int[], T> yieldF) {
return yieldF(....num2, ....arr2); //and again...
}
//...
var anontuple = MyFunction(3+4+5, (intp, arrp) => new { IntP = intp, ArrP = arrp, });
int foobar = anontuple.IntP + anontuple.ArrP[0];//with intellisense...