In this article, we will learn and implement five different ways to return multiple values from a C# method.
Returning multiple values to a method caller in C# can be useful when we need to return more than one value from a method, and we cannot call multiple methods to have each one returned separately.
Let’s make a start.
Return Multiple Values Using Tuple
Before we start coding, let’s create a console application using the Visual Studio wizard or the dotnet new console
command.
In this first approach, we are going to return multiple values to a method caller using the Tuple
class.
Tuple is a data structure that allows us to store multiple values in a single object.
Let’s create a method to return several values at once:
public static Tuple<string, bool, int> GetValuesUsingTuple() { var stringValue = "Some String Value"; var boolValue = false; var intValue = int.MaxValue; return Tuple.Create(stringValue, boolValue, intValue); }
This method returns a Tuple
instance and doesn’t receive any input parameter.
First, we declare three local variables (stringValue
, boolValue
, and intValue
) and assign some values to them.
Then, we create a new tuple using the Tuple.Create()
method and return the three values at once.
Now, let’s call this method to retrieve the results:
var tuple = MultipleValuesReturner.GetValuesUsingTuple();
To access the returned value, we should use tuple.Item1
, tuple.Item2
, tuple.Item3
that represents the three returns respectively:
Console.WriteLine(tuple.Item1); // Some String Value Console.WriteLine(tuple.Item2); // false Console.WriteLine(tuple.Item3); // 2147483647
Or we can use tuple destructuring (tuple unpacking operation) to extract these values from a tuple and store them in individuals variables:
var (stringValue, boolValue, intValue) = MultipleValuesReturner.GetValuesUsingTuple(); Console.WriteLine(stringValue); // Some String Value Console.WriteLine(boolValue); // false Console.WriteLine(intValue); // 2147483647
Use Tuple Literals to Return Multiple Values
Since C# 7, we can use the tuple literals to have the same result. Let’s implement another method to check this approach:
public static (string stringValue, bool boolValue, int intValue) GetValuesUsingTupleLiterals() { var stringValue = "Some String Value"; var boolValue = false; var intValue = int.MaxValue; return (stringValue, boolValue, intValue); }
These two methods (GetValuesUsingTupleLiterals()
and GetValuesUsingTuple()
) are similar in that they both use tuples to return multiple values in a single object. However, when using tuple literals in the method signature, the Tuple<type, ...>
is not necessary. Instead, we can list the value types we want to return, separated by commas.
Then, we can use the tuple destructuring technique to receive the values.
Use Out Keyword
In this second approach, we will learn how to return multiple values to a method caller using the out keyword.
When we use the out
keyword, we can pass variables to a method, so, the method can assign values to these variables. Let’s implement a new method to check how to use it:
public static void GetValuesUsingOutKeyword(out string stringValue, out bool boolValue, out int intValue) { stringValue = "Some String Value"; boolValue = false; intValue = int.MaxValue; }
In this technique, the GetValuesUsingOutKeyword()
method doesn’t need any return type. However, it takes three variables as input parameters to store the values we want to return.
Then, we assign values to the variables that we received as parameters.
Let’s call this method:
string stringValue; bool boolValue; int intValue; MultipleValuesReturner.GetValuesUsingOutKeyword(out stringValue, out boolValue, out intValue);
First, we create three variables (stringValue
, boolValue
, and intValue
). Then, using the out
keyword, we pass these variables to the GetValuesUsingOutKeyword()
method.
Now, let’s analyze the result:
Console.WriteLine(stringValue); // Some String Value Console.WriteLine(boolValue); // false Console.WriteLine(intValue); // 2147483647
After invoking the GetValuesUsingOutKeyword()
method, the values of the variables stringValue
, boolValue
and intValue
are set.
Use an Object to Return Multiple Values
To return multiple values to a method caller, we can use an object instance. This approach gives us great flexibility for a larger and more complex data structure. Let’s demonstrate this by creating a MultipleValues
class with three properties:
public sealed class MultipleValues { public required string StringValue { get; set; } public bool BoolValue { get; set; } public int IntValue { get; set; } }
To avoid having to define a default value for the StringValue
property, we have set it with the required keyword.
Now, let’s create a method to return our class:
public static MultipleValues GetValuesUsingObjectInstance() { return new MultipleValues { StringValue = "Some String Value", BoolValue = false, IntValue = int.MaxValue }; }
Here, we create a new instance of the MultipleValue
class, initialize its properties with some values, and finally return this object instance.
Let’s call this method and check how to use it:
var multipleValues = MultipleValuesReturner.GetValuesUsingObjectInstance(); Console.WriteLine(multipleValues.StringValue); // Some String Value Console.WriteLine(multipleValues.BoolValue); // false Console.WriteLine(multipleValues.IntValue); // 2147483647
Use Collections to Return Multiple Values
It is worth mentioning that we can use collections to return multiple values to a method caller. To demonstrate this, we will use two different collections: a dictionary and an array of objects. However, we can choose any kind of collection.
Let’s check it.
Use a Dictionary to Return Multiple Values
So, one way to return multiple values from a method is by using a Dictionary.
Let’s implement a method to check this approach:
public static Dictionary<string, object> GetValuesUsingDictionary() { var results = new Dictionary<string, object>(); results.Add("stringValue", "Some String Value"); results.Add("boolValue", false); results.Add("intValue", int.MaxValue); return results; }
This method returns a Dictionary
with a string key and object value.
First, we instantiate a new dictionary that will contain a string representing the key and an object representing the value.
Then, we populate this dictionary with some values.
Finally, we return the result dictionary with all these values.
Using a dictionary allows us to access our return values by doing a key lookup, let’s check it:
var multipleValues = MultipleValuesReturner.GetValuesUsingDictionary(); Console.WriteLine(multipleValues["stringValue"]); // Some String Value Console.WriteLine(multipleValues["boolValue"]); // false Console.WriteLine(multipleValues["intValue"]); // 2147483647
To use it, first, we call GetValuesUsingDictionary()
and store the result in a multipleValues
object.
Then, we print the value associated with each key in the dictionary.
Use an Array of Objects to Return Multiple Values
In this last approach, we are going to use an object array to return multiple values.
Let’s implement a new method:
public static object[] GetValuesUsingArrayOfObject() { return new object[] { "Some String Value", false, int.MaxValue }; }
The GetValuesUsingArrayOfObject()
method returns an object array with our string
, bool
and int
values.
Let’s analyze how to call this method and read its result:
var multipleValues = MultipleValuesReturner.GetValuesUsingArrayOfObject(); Console.WriteLine(multipleValues[0]); // Some String Value Console.WriteLine(multipleValues[1]); // false Console.WriteLine(multipleValues[2]); // 2147483647
First, we call the GetValuesUsingArrayOfObject
method. Next, we print each index of the multipleValues
array.
Note that, in this scenario, we chose to use an array of objects. However, any collection of objects would work just as well.
It is important to mention that we are using objects because we have different data types. If all our data is of the same type (such as only integers), we should create an array of that specific type.
Conclusion
In this article, we have learned about five different techniques for returning multiple values to a method caller in C#, such as Tuples, the out keyword, object instance, dictionaries, and arrays of objects. Each technique with its own strengths and limitations.
After examining these five approaches, we can see that when we use Tuple we have a concise syntax and strong type safety, making it a good choice for a small set of values. However, the object instance provides us with great flexibility for larger and more complex data structures.
After all, it is important to mention that we can use any of these approaches to reproduce the same result, so it is up to us to decide which one fits better to our projects.