Methods in C# return only one value. This value can be an object with multiple fields. Several options are available for returning multiple values from a method.
If we need to return multiple values, we can use out parameters or return a type instance (like a tuple) containing all the values. We benchmark and compare approaches.
There are many ways to return multiple parameters in the C# language. Modern versions of C# provide tuple syntax which are probably the most elegant.
KeyValuePair
instance to store the result values. The calling location can access the Key and Value.ValueTuple
) can also be used. We can specify a tuple within parentheses.Tuple
class
. We must specify the types as generic arguments.GetTwoNumbers
methods return the same 2 ints. We verify this by printing the return values.using System; using System.Collections.Generic; class Program { static void GetTwoNumbersA(out int number1, out int number2) { // Part 1: assign out parameters. number1 = 1; number2 = 2; } static KeyValuePair<int, int> GetTwoNumbersB() { // Part 2: return KeyValuePair. return new KeyValuePair<int, int>(1, 2); } static (int, int) GetTwoNumbersC() { // Part 3: return tuple. return (1, 2); } static Tuple<int, int> GetTwoNumbersD() { // Part 4: return Tuple class. return new Tuple<int, int>(1, 2); } static void Main() { // Part 5: test all the methods and ensure their output is identical. GetTwoNumbersA(out int number1, out int number2); Console.WriteLine($"{number1} {number2}"); var resultB = GetTwoNumbersB(); Console.WriteLine($"{resultB.Key} {resultB.Value}"); var resultC = GetTwoNumbersC(); Console.WriteLine($"{resultC.Item1} {resultC.Item2}"); var resultD = GetTwoNumbersD(); Console.WriteLine($"{resultD.Item1} {resultD.Item2}"); } }1 2 1 2 1 2 1 2
There are multiple ways to return multiple values from a method. The most common ones are probably out
-parameters and KeyValuePair
and tuples.
KeyValuePair
and read in its Key and Value properties from the returned method.Item1
and Item2
.using System; using System.Collections.Generic; using System.Diagnostics; class Program { static void GetTwoNumbersA(out int number1, out int number2) { number1 = 1; number2 = 2; } static KeyValuePair<int, int> GetTwoNumbersB() { return new KeyValuePair<int, int>(1, 2); } static (int, int) GetTwoNumbersC() { return (1, 2); } static void Main() { const int max = 100000000; var s1 = Stopwatch.StartNew(); // Version 1: use 2 out parameters. for (int i = 0; i < max; i++) { int a; int b; GetTwoNumbersA(out a, out b); if (a + b != 3) { throw new Exception(); } } s1.Stop(); var s2 = Stopwatch.StartNew(); // Version 2: return KeyValuePair. for (int i = 0; i < max; i++) { var pair = GetTwoNumbersB(); int a = pair.Key; int b = pair.Value; if (a + b != 3) { throw new Exception(); } } s2.Stop(); var s3 = Stopwatch.StartNew(); // Version 3: return tuple. for (int i = 0; i < max; i++) { var tuple = GetTwoNumbersC(); int a = tuple.Item1; int b = tuple.Item2; if (a + b != 3) { throw new Exception(); } } s3.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / max).ToString("0.00 ns")); Console.WriteLine(((double)(s3.Elapsed.TotalMilliseconds * 1000000) / max).ToString("0.00 ns")); } }1.90 ns out 7.59 ns KeyValuePair 7.64 ns tuple
Multiple values can be returned from a method invocation. We used out to pass parameters by reference. With KeyValuePair
and Tuple
we returned multiple values in a container.