Ask Learn
Preview
Please sign in to use this experience.
Sign inThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Starting today I will start a new C# 7 series, to introduce new language features of C# 7+ features. Please note that I am not saying C# 7.0, I am saying C# 7 plus, because there will be minor language versions (like 7.1, 7.2) that will bring new features in steps (thanks to Roslyn!) such as async Main and default literals.
The System.Tuple class provides a type to represent a key-value like property bag. It can be used where you want to have a data structure to hold an object with properties (elements) but you don’t want to create a separate type for it. The following code shows how you use it as a return value of a method that holds the name and the age of a student.
public Tuple<string, int> GetStudentInfo(string id)
{
// Search by ID and find the student.
return new Tuple<string, int>("Annie", 25);
}
As you can see, I am returning an instance of Tuple<string, int> object with first argument is the name and the second argument is the age. Later on we can have code to call this method, like this:
public void Test()
{
Tuple<string, int> info = GetStudentInfo("100-000-1000");
Console.WriteLine($"Name: {info.Item1}, Age: {info.Item2}");
}
You can access name and age by referencing Item1 and Item2.
The Tuple class has some obvious problems:
C# 7.0 introduced ValueTuple structure, which is a value type representation of the tuple object. The language team made many good things for this value tuple type, including a new syntax and many features (such as deconstruction.)
The following is a rewrite version with the value tuples, Note that if you don’t see the ValueTuple available in your project, you have to download the System.ValueTuple 4.3.0 NuGet package to your project. You don’t need to do anything if you are using .NET Framework 4.7 or higher, or .NET Standard Library 2.0 or higher.
public (string, int) GetStudentInfo(string id)
{
// Search by ID and find the student.
return ("Annie", 25);
}
public void Test()
{
(string, int) info = GetStudentInfo("100-000-1000");
Console.WriteLine($"Name: {info.Item1}, Age: {info.Item2}");
}
The code above is much simplified by using the first-class syntax ().
You can even give a name to every element in the value tuple, like this:
public (string name, int age) GetStudentInfo(string id)
{
// Search by ID and find the student.
return (name: "Annie", age: 25);
}
public void Test()
{
(string name, int age) info = GetStudentInfo("100-000-1000");
Console.WriteLine($"Name: {info.name}, Age: {info.age}");
}
Perfect! Now you have good metadata for the elements in tuple objects, you then don’t need to go back and forth to make sure you are returning/accessing elements in the right order as its original definition.
The Visual Studio IDE will give you hints when you work with the value tuples.
You can deconstruct the elements from the value tuple object, and access the local variables.
// Deconstruct using the var (x, y) syntax,
// or (var x, var y) syntax.
var (name, age) = GetStudentInfo("100-000-1000");
// Now you have two local variables: name and age.
Console.WriteLine($"Name: {name}, Age: {age}");
If you just care about certain elements but not all, you can use the _ keyword to ignore the local variable.
// Deconstruct using the var (x, y) syntax,
// or (var x, var y) syntax.
var (name, _) = GetStudentInfo("100-000-1000");
// Now you have just one local variable: name. The value for age is ignored.
Console.WriteLine($"Name: {name}");
The System.Tuple and System.ValueTuple provides some extension methods to help convert between Tuple and ValueTuple.
var valueTuple = (id: 1, name: "Annie", age: 25, dob: DateTime.Parse("1/1/1993"));
var tuple = valueTuple.ToTuple();
ValueTuple makes the C# language more modern, and easy to use with simplified syntax. It solves many Tuple problems:
Since the name of the value tuple element is not runtime, you have to be careful using it when doing serialization with existing libraries, such as Newtonsoft.Json, Unless the library updated to support the new metadata (TupleElementNameAttribute etc.) before then you would run into bugs.
Please sign in to use this experience.
Sign in