Problem Statement
You want to return multiple results from a single method of different types.
To achieve this functionality, there were three methodologies until Framework version 4.6.* and they are the following.
Method 1- Using out parameters
As a .NET developer working since framework 3.5, I'm well aware of the out parameter feature using which, we can send these as parameters to the method where it should be assigned with appropriate data.
Disadvantage
Out and ref parameters are not supported in Async methods.
Method 2 - System.Tuple Type
This is a new type introduced in Framework 4.0, where it has the scope to return up to 8 component values from a single method.
Disadvantages
As this Tuple type is a reference type and stored, more data will be heaped onto memory overhead and GC process time to clear the objects.
When we get the output of Tuple types, parameter names will be by default as Item1, Item2, etc.. There is no scope to give custom names for this.
Method 3 - POCO Class
This is a traditional way to capture multiple results in a single return object. Using POCO class we can declare all result variables as properties and can return from the given method.
Disadvantage
There will be some overhead creating multiple POCO classes and managing them, and also this will be a reference type and again the same heap memory overhead.
By keeping all these points in consideration, the team came up with a solution called Value Tuple data structure in the latest C# 7.0 and .NET framework 4.7.
How will this ValueTuple overcome above problems?
Firstly, System.ValueTuple is a structure (struct type) so as we know struct can be treated, as value type will not occupy heap memory and instead works with stack memory.
Following are the declarations,
- public struct ValueTuple : IEquatable<ValueTuple>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple>
Let’s dig in to know how to work with ValueTuples.
System.ValueTuple won’t come with the framework 4.7 package, instead we need to install it from the NuGet package as shown below.
We can declare this type in two ways.
Declaration 1
Here this declaration is of of the method we are trying to return -- student name and address.
- public(string, string) GetStudentNameAddress(int studentId) {
- return ("Sai", "Hyderabad");
- }
As you can see the above method demonstrates how to return and declare a method using valueType. Below is the statement where we are trying to assign these return values to an object.
- Var result = GetStudentNameAddress(10);
- Console.writeline($ "{result.Item1} and {result.Item2}");
As you can observe in the above statement still we are not comfortable with Item1 and Item2. To overcome this we have a feature in ValueType where it supports named properties which are demonstrated in Declaration 2.
Declaration 2
As explained above, this declaration will be better with custom named parameters.
- public(string Name, string Address) GetStudentNameAddress(int studentId) {
- return ("Sai", "Hyderabad");
- }
As observed we can give a type and name of the parameter, and the same will be passed to result in a variable as follows.
- Var result = GetStudentNameAddress(10);
- Console.writeline($ "{result.Name} and {result.Address}");
Now we solved the issue of Item1 and 2 with our custom names.
For more ease, we can even have the following styles of usage which are self-explanatory.
Style 1
- Var result = GetStudentNameAddress(10);
Style 2
- (string Name, string Address) = GetStudentNameAddress(10);
Style 3
- String (Name, Address) = GetStudentNameAddress(10);
Hope you understand well, please comment here if you have any concerns.
Happy coding.