Multiple Return Values
This page was last reviewed on Mar 19, 2022.
Dot Net Perls
Multiple return values. Methods in C# return only one value. This value can be an object with multiple fields. Many options are available for returning multiple values from a method.
Out keyword. If you need to return multiple values, you can use out parameters or return a type instance containing all the values. We benchmark and compare approaches.
An example. There are 2 ways of returning multiple values using output parameters. We can use formal parameters modified by the out keyword.
Detail We can allocate a KeyValuePair instance to store the result values. A Tuple (or ValueTuple) can also be used.
Info The first GetTwoNumbers() uses 2 output parameters. It assigns the storage locations (for the out parameters) in the method body.
Next The second GetTwoNumbers() returns a KeyValuePair generic struct instance instead of using output parameters.
Detail The 2 numbers are specified as the key and value of the struct. And this struct is returned.
using System; using System.Collections.Generic; class Program { static void GetTwoNumbers(out int number1, out int number2) { number1 = (int)Math.Pow(2, 2); number2 = (int)Math.Pow(3, 2); } static KeyValuePair<int, int> GetTwoNumbers() { return new KeyValuePair<int, int>((int)Math.Pow(2, 2), (int)Math.Pow(3, 2)); } static void Main() { // Use out parameters for multiple return values. int value1; int value2; GetTwoNumbers(out value1, out value2); Console.WriteLine(value1); Console.WriteLine(value2); // Use struct for multiple return values. var pair = GetTwoNumbers(); Console.WriteLine(pair.Key); Console.WriteLine(pair.Value); } }
4 9 4 9
ValueTuple example. We can use a ValueTuple to return multiple values from a method. Consider this program. We must ensure the ValueTuple package is included before using it.
Detail The ValueTuple has excellent performance. When available, this type should be used—it is used in a similar way to Tuple.
using System; class Program { static (int, int) GetTwoNumbers() { // Return 2 numbers in a ValueTuple. return (10, 20); } static void Main() { var result = GetTwoNumbers(); Console.WriteLine(result.Item1); Console.WriteLine(result.Item2); } }
10 20
Benchmark. There are multiple ways to return multiple values from a method. The most common ones are probably out-parameters and KeyValuePair and tuples.
Version 1 This version of the code uses out parameters to return 2 values from a method.
Version 2 Here we use a KeyValuePair and read in its Key and Value properties from the returned method.
Detail A tuple can be used to return 2 values from a method. We access Item1 and Item2.
Result The first implementation, which uses out parameters, was found to be somewhat slower than the second, which uses the KeyValuePair.
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 Tuple<int, int> GetTwoNumbersC() { return new Tuple<int, int>(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.64 ns, out 0.32 ns, KeyValuePair 5.40 ns, Tuple
A summary. 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.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Mar 19, 2022 (edit).
© 2007-2024 Sam Allen.