TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

C# Multiple Return Values

This C# article shows how to return multiple values from a method. It uses out and ref parameters and KeyValuePair.

Multiple return values.

Methods return only one value. This value can be an object with multiple fields. If you need to return multiple values from a method, you can use out parameters or return a type instance containing all the values.

Note: These approaches require different syntax forms. They result in different performance metrics.

Return

Example. There are two ways of returning multiple values using output parameters. We can use formal parameters modified by the out keyword. Alternatively, we can allocate a KeyValuePair instance to store the result values.

Tip: Instead of KeyValuePair you could use a custom class or the Tuple type from the .NET Framework 4.0.

C# program that uses multiple return values

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);
    }
}

Output

4
9
4
9

The first version of the GetTwoNumbers method uses two output parameters, which are described with the out modifier. This version assigns the storage locations passed in by the out parameters in the method body.

OutMath.Pow

KeyValuePair. The program also describes an alternate GetTwoNumbers method, which is ordered second in the lexical source. This version returns a KeyValuePair generic struct instance instead of using output parameters.

KeyValuePairStruct

Then: The two numbers are specified as the key and value of the struct. And this struct is returned.

Performance. We next consider the performance aspects of returning multiple values. The first implementation, which uses out parameters, was found to be somewhat slower than the second, which uses the KeyValuePair.

In this benchmark, inlining might account for why out parameters were slower. The compiler might be less likely to inline a method that uses out parameters. The KeyValuePair is allocated on the stack, so it ends up being faster.

And: The Tuple, meanwhile, is allocated on the heap which ends up being much slower.

Warning: This benchmark is based on a 32-bit Windows installation. It gives different results for a 64-bit version.

C# program that benchmarks multiple return values

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();
	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();
	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();
	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"));
	Console.Read();
    }
}

Results

1.64 ns,    out
0.32 ns,    KeyValuePair
5.40 ns,    Tuple

Summary. Multiple values can be returned from a method invocation. We used out to pass parameters by deference. With KeyValuePair and Tuple we returned multiple values in a container. We benchmarked these approaches.


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf