C# 7.0 - Tuples To The Extreme!

Tuples are something that many developers may not frequently work with on a day-to-day basis, but they have a few different uses. With the latest upcoming release of C# however, this may change as tuples are getting a major power-up and will likely see quite a bit more "play" in the real-world.

So what is a Tuple?

If we go by the MSDN description:

A tuple is a data structure that has a specific number and sequence of elements. An example of a tuple is a data structure with three elements (known as a 3-tuple or triple) that is used to store an identifier such as a person's name in the first element, a year in the second element, and the person's income for that year in the third element.

Or more basically, you can think of it as a class without any actual properties or something that you might use if you are too lazy to actually create a class to implement some type of behavior.

For example, let's say you wanted to create a class to store a City / State combination that you might pass around.

  1. public class Location    
  2. {  
  3.      public string City { get; set; }  
  4.      public string State { get; set; }  
  5.   
  6.      public Location(string city, string state)  
  7.      {  
  8.            City = city;  
  9.            State = state;  
  10.      }  
  11. }  
  12.   
  13. // Example  
  14. var location = new Location("Lake Charles","LA");    
  15. // Print out the address  
  16. var address = $"{location.City}, {location.State}";    
  17. You could do the same thing with a Tuple, however you would obviously have much less descriptive things to work with:  
  18. var location = new Tuple<string,string>("Lake Charles","LA");    
  19. // Print out the address  
  20. var address = $"{location.Item1}, {location.Item2}";     

So, in some scenarios, especially quick and dirty ones, Tuple objects can be incredibly useful. MSDN also has a few common use cases that you might wanted to look over as well.

Alright. So what's new with Tuples in C# 7.0?

Well, C# 7.0 introduces a feature that I know quite a few developers have been asking about for a while: multiple return values.

That's right, you can now write some code like the following without having to build a class, use a tuple, or a series of ref or out parameters, 

  1. public (string city, string state) GetCityAndState()    
  2. {  
  3.     return ("Lake Charles","Louisiana");  
  4. }   

This would allow you to make a call to a single method and access each of the return values by their defined names as seen below, 

  1. var result = GetCityAndState();    
  2. var city = result.city;  // yields "Lake Charles"    
  3. var state = result.state // yields "Louisiana"  

The results of these multiple return value methods can also be deconstructed in a variety of ways based on your needs, 

  1. // Using two explicitly defined return values  
  2. (string city, string state) = GetCityAndState();  
  3. // Using var as opposed to explicit type definitions  
  4. (var city, var state) = GetCityAndState();  
  5. // Using a single var declaration for multiple variables  
  6. var (city, state) = GetCityAndState();    
  7. // Using existing variables  
  8. (city,state) = GetCityAndState();   

As you might imagine, initialization is going to roughly take a similar syntactic approach:

  1. var location = ("Lake Charles""Louisiana");   

This is a feature that a few other popular programming languages like Python, Scala, Ruby, Go and others have had for quite a while, so hopefully it will be a nice addition to C#.

Cool. Anything else?

In addition to straight-forward examples like those provided, these new ValueTuple objects can use things like type inference to match up the signature of the return type and ensure it is valid like the following example, 

  1. public (string city, int population) FindBiggestCityWithPopulation(string state)    
  2. {  
  3.     var result = (city: "", population: 0);  
  4.     result.city = _someService.GetBiggestCity(state);  
  5.     result.population = _someService.GetPopulation(result.city);  
  6.     return result;  
  7. }   

Likewise, these new tuples also support the async/await pattern out of the box, 

  1. public async Task<(string bird, string flower)> GetStateBirdAndFlowerAsync(string state)    
  2. {  
  3.     var bird = await _someService.GetStateBirdAsync(state);  
  4.     var flower = await _someService.GetStateFlower(state);  
  5.     return (bird,flower);  
  6. }   

See how this came to be.

One of the wonderful things about the "new" Microsoft development ecosystem is just how open it is. No longer are important development decisions mad in dark, smoke-filled rooms but rather in transparent issues on GitHub.

If you want to take a look at the conversation that lead up to this feature, you can visit the proposal for multiple return values here. You may also want to consider looking around through the other active issues to see what other features might be coming soon.