Frederik Today

Returning Multiple Values From a Class Method

It is not rare for you to want to return several values from a class method, but you don't need the full class. The options available in older versions of C# are less than optimal:

Previous Available Solutions

  • Out parameters: They don’t work with async methods.
  • System.Tuple<...> Require an allocation of a tuple object.
  • Custom-built transport type for every method: A lot of code overhead.
  • Anonymous types returned through a dynamic return type: High performance-overhead and no static type checking.

A Better Way (From C#7)

Let's say we are having a class Users, with a lot of fields, like Name, FirstName, Department, PhoneNumber, CurrentWorkingOnStatus, Email,... Inside your app, on many occasions, you request to have the FirstName and the CurrentWorkingOnStatus.

The User Class

public sealed class User
{
public int id { get; set; }
public string Name { get; set; }
public string FirstName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Status { get; set; }

/// Many Other fields
public User() { }
public User(int userid) { }

public void Deconstruct(out string name, out string status)
{
name = FirstName;
status = Status;
}

public static User GetCurrentUserStatus(int userid)
{
return new User() {FirstName= "Frederik"
, Status = "Building CodeHelper NuGet Packages" };
}
}
The Deconstruct method lets you unpackage all the items in a tuple in a single operation but can also be used with your class!

The Code

The code will call GetCurrentUserStatus method, the return will be "deconstructed" into the 2 variables userName and userStatus.
var (_userName, _userStatus) = User.GetCurrentUserStatus(123);
Console.WriteLine($"{ userName} is working on {userStatus}");
In case you want to get the full class data back, with access to all properties ad methods, you still can do it
User _trending = User.GetCurrentUserStatus();
///-- You have access to a properties

Multiple Deconstruct Methods?

Yes, it is possible to create multiple deconstruct methods, as long as they have a different number of out parameters Add the following method to the user class
public void Deconstruct(out string name, out string email, out string phone) { 
name = Name + " " + FirstName;
email = Email;
phone = Phone;
}
Add the following code to your app
var (_user, _email, phone) = User.GetContactinfo(123);
Console.WriteLine($"{
user} can be contacted by phone {_phone}");

Solution without the Deconstruct Method

It is not always the best way to create many deconstruct methods, you can return multiple values from your class methods directly Add the following method the user class
public static (string name, string firstname) GetUserName()
{
return ("Van Lierde", "Frederk");
}
Add the following code to your app
var (_name, _fname) = User.GetUserName();
Console.WriteLine($"Coder: {name} {fname}");

Benchmark

|           Method |     Mean |    Error |   StdDev |   Median | Allocated |
|----------------- |---------:|---------:|---------:|---------:|----------:|
| returnDestructor | 15.72 ns | 0.808 ns | 2.357 ns | 15.87 ns | 64 B |
| returnClass | 18.15 ns | 1.288 ns | 3.757 ns | 16.52 ns | 64 B |

Conclusion

These C# features make your code more readable, understandable and it is a litte faster