English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# ValueTuple (Value Tuple)

C#7.0 (.NET Framework 4.7) introduced the ValueTuple structure, which is a value type representation of tuples.

ValueTuple is available only in .NET Framework 4.7available. If you do not see ValueTuple in your project, you need to install ValueTuple. (.NET Framework 4.7Or higher version, or .NET Standard Library 2.0 or a higher version already includes ValueTuple.)

To install the ValueTuple package, right-click on the project in the Solution Explorer, and then selectManage NuGet Packages... This will open the NuGet package manager. ClickBrowsetab, search for ValueTuple in the search box, and then selectSystem.ValueTuplepackage, as shown below.

ValueTuple initialization

Creating and initializing ValueTuple is easy. You can create and initialize it by using parentheses () and specifying the values within them.

var person = (1, "Bill", "Gates");    
//Equivalent tuple
//var person = Tuple.Create(1,“ Bill”,“ Gates”);"Bill", "Gates");

You can also initialize ValueTuple by specifying the type of each element, as shown below.

ValueTuple<int, string, string> person = (1, "Bill", "Gates");
person.Item1;  // Return1
person.Item2;   // Return "Bill"
person.Item3;   // Return "Gates"

Here is a shorthand method for declaring types for each member.

(int, string, string) person = (1, "Bill", "Gates");
person.Item1;  // Return1
person.Item2;   // Return "Bill"
person.Item3;   // Return "Gates"

Please note that we did not use var in the above tuple initialization statement, instead, we provided the type of each member value within the brackets.

A tuple must have at least two values. The following is not a tuple:

var number = (1);  // int type, not a tuple
var numbers = (1,2); // Valid tuples

Unlike Tuple, ValueTuple can contain more than eight values.

var numbers = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);

Named members

We can assign names to ValueTuple properties instead of using default property names, such as Item1, Item2etc.

(int Id, string FirstName, string LastName) person = (1, "Bill", "Gates");
person.Id;   // Return1
person.FirstName;  // Return "Bill"
person.LastName; // Return "Gates"

We can also assign values to member names on the right, as shown below.

var person = (Id:1, FirstName: "Bill", LastName: "Gates");

Please note that we can provide member names on the left or right, but we cannot provide member names on both sides. The left takes precedence over the right. The following content will ignore the names on the right.

// PersonId, FName, LName will be ignored.
(int Id, string FirstName, string LastName) person = (PersonId:1, FName: "Bill", LName: "Gates");
//PersonId, FirstName, LastName will be ignored. It will have default names: Item1, Item2, Item3.
(string, string, int) person = (PersonId:1, FName: "Bill", LName: "Gates");

We can also assign variables as member values.

string firstName = "Bill", lastName = "Gates";
var per = (FirstName: firstName, LastName: lastName);

ValueTuple as return type

The following method returns a ValueTuple.

static void Main(string[] args)
{
    DisplayTuple(1, "Bill", "Gates");
}
static void DisplayTuple((int, string, string) person)
{
    Console.WriteLine($"Id = { person.Item1});
    Console.WriteLine($"First Name = { person.Item2});
    Console.WriteLine($"Last Name = { person.Item3});
}

We can also specify different member names for the ValueTuple returned by the method.

static void Main(string[] args)
{          var person = GetPerson();
}
static (int, string, string) GetPerson()} 
{          return (Id:1, FirstName: "Bill", LastName: "Gates");
}

Destructuring

We can retrieve its individual members by destructuring a ValueTuple. The destructuring declaration syntax splits the ValueTuple into multiple parts and assigns each part to a new variable separately.

static void Main(string[] args)
{  
    // Change property name
    (int PersonId, string FName, string LName) = GetPerson();
}
static (int, string, string) GetPerson()} 
{          return (Id:1, FirstName: "Bill", LastName: "Gates");
}

We can also use var instead of explicit data type names.

static void Main(string[] args)
{    
    // Use var as the data type
    (var PersonId, var FName, var LName) person = GetPerson();
}
static (int, string, string) GetPerson()} 
{ 
   return (Id:1, FirstName: "Bill", LastName: "Gates");
}

ValueTuple also allows for 'discard' deconstruction of unused members.

// Use an underscore _ to discard unused member LName
(var id, var FName, _) = GetPerson();