DEV Community

Frederik Van Lierde
Frederik Van Lierde

Posted on

Returning Multiple Values From a Class Method (but not the full class)

update: added benchmark

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" };
   }
}
Enter fullscreen mode Exit fullscreen mode

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}");
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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; 
        }
Enter fullscreen mode Exit fullscreen mode

Add the following code to your app

var (_user, _email, _phone) = User.GetContactinfo(123);
Console.WriteLine($"{_user} can be contacted by phone  {_phone}");
Enter fullscreen mode Exit fullscreen mode

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");  
}
Enter fullscreen mode Exit fullscreen mode

Add the following code to your app

var (_name, _fname) = User.GetUserName();
Console.WriteLine($"Coder: {_name} {_fname}");
Enter fullscreen mode Exit fullscreen mode

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 |
Enter fullscreen mode Exit fullscreen mode

Conclusion

These C# features make your code more readable, understandable and you use much less memory

Top comments (0)