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.
- public class Location
- {
- public string City { get; set; }
- public string State { get; set; }
-
- public Location(string city, string state)
- {
- City = city;
- State = state;
- }
- }
-
-
- var location = new Location("Lake Charles","LA");
-
- var address = $"{location.City}, {location.State}";
- You could do the same thing with a Tuple, however you would obviously have much less descriptive things to work with:
- var location = new Tuple<string,string>("Lake Charles","LA");
-
- 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,
- public (string city, string state) GetCityAndState()
- {
- return ("Lake Charles","Louisiana");
- }
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,
- var result = GetCityAndState();
- var city = result.city;
- var state = result.state
The results of these multiple return value methods can also be deconstructed in a variety of ways based on your needs,
-
- (string city, string state) = GetCityAndState();
-
- (var city, var state) = GetCityAndState();
-
- var (city, state) = GetCityAndState();
-
- (city,state) = GetCityAndState();
As you might imagine, initialization is going to roughly take a similar syntactic approach:
- 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,
- public (string city, int population) FindBiggestCityWithPopulation(string state)
- {
- var result = (city: "", population: 0);
- result.city = _someService.GetBiggestCity(state);
- result.population = _someService.GetPopulation(result.city);
- return result;
- }
Likewise, these new tuples also support the async/await pattern out of the box,
- public async Task<(string bird, string flower)> GetStateBirdAndFlowerAsync(string state)
- {
- var bird = await _someService.GetStateBirdAsync(state);
- var flower = await _someService.GetStateFlower(state);
- return (bird,flower);
- }
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.