C# Tuples as Syntactic Sugar for Multiple Variable Assignment

Published 12 Jun 2020

  • Patterns and Practices

I came across an interesting pattern for using Tuples in an article by Mads Torgersen on C# 9.0 . At first I thought it must be something new in 9.0, but a little digging and actually engaging my brain made me realise it has been possible since C# 7.0 and the introduction of Tuples. It isn't something I've seen anybody else use so I thought it would be worth writing about.Ā 

I have to admit that I've not really looked at Tuples that much and learning a bit more about them reveals some features that allow a style of assignment through destructuring that is ubiquitous in modern JavaScript.

Here is the bit of code from Mads' article that triggered my curiosity (expression bodies wrapped by me for legibility online):

At this point in his article he is actually explaining records using the data keyword (very cool). These feature new init-only properties and are intended as value-like immutable data. He offers the above example as a positional approach to record creation and usage. I have to admit I'd not known about the Deconstruct method which assigns values to any number of out variables. We'll get to that below, but the bit that initially caught my eye was the constructor. Both properties are wrapped in parentheses, as are the two constructor parameters, so the assignments are both done in one line. So what's going on here?

The answer, as I've alluded to above, is Tuple deconstruction. The normal way that you consume tuples as return types is to create the variables in the expression:

The bit that I was not aware of is tucked away at the end of the section on deconstruction in the tuple docs , where it says that you can deconstruct tuples with existing declarations as well, which is what Mads has done. So the code creates a tuple of the existing declared variables, and one from the arguments and assigns values from one to the other.

As a side note, it is worth pointing out that you cannot mix existing declarations with declarations inside the parentheses, it is one or the other.

Why is this a useful pattern to consider? The answer is brevity and readability. Let's look at an example with a simple class and constructor. The standard approach would look like this:

with the destructuring syntax this becomes:

and now we have a shorter single line expression we can also use that other bit of syntactic sugar, the expression body, so we can get the whole constructor on one line:

Many of the improvements that have been applied to C# over the years have been about the reduction in the amount of boilerplate code you need to write, what Jon Skeet refers to as "ceremony". It is about getting the compiler to do the work for you so you can get on with the task at hand. Now you always have to be wary of when terseness turns into obscurity. However, in this case I would argue that this approach is actually more easy to read and comprehend than the traditional approach - it is quite expressive of the intent which is why I like it as a pattern.

JavaScript Style Destructuring

I promised to get back to the Deconstruct method, as this can bring a similar reduction in ceremony, that makes some code that looks very JavaScript-like. As a reminder, Mads' example featured this line:

The power of this method is that it can be used to assign variables like this:

This is why I say it is a strong parallel to JavaScript object destructuring where you would see something like this:

Where this gets really interesting is that you can apply a Deconstruct method to types you have not created via extension methods, so you can use this brief destructuring syntax wherever you want like this:

You can create multiple Deconstruct methods with different out parameters, but this could get confusing and create more work than it saves. As an alternative you can have single/fewer methods and use Discards , another C# 7.0 feature that I've not used. This uses the underscore to assign a temporary dummy variable that is never used by your application. You use it like this:

Ā I've never really spent much time exploring tuples because I've preferred to instantiate return values as types. I've not found situations where those types felt like an overhead. I'm not sure I've changed my stance on that after spending a bit more time investigating them, but this ability to add a Deconstruct extension to a class to enable destructuring assignment is interesting and I'm going to be looking out for opportunities to use this approach to see how it works.

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

August 2017

Volume 32 Number 8

[Essential .NET]

C# 7.0: tuples explained.

By Mark Michaelis

Mark Michaelis

To begin, letā€™s consider the question: Why tuples? On occasion, youā€™ll likely find it useful to combine data elements. Suppose, for example, youā€™re working with information about countries, such as the poorest country in the world in 2017: Malawi, whose capital is Lilongwe, with a gross domestic product (GDP) per capita of $226.50. You could obviously declare a class for this data, but it doesnā€™t really represent your typical noun/object. Itā€™s seemingly more a collection of related pieces of data than it is an object. Surely, if you were going to have a Country object, for example, it would have considerably more data than just properties for the Name, Capital and GDP per capita. Alternatively, you could store each data element in individual variables, but the result would be no association between the data elements; $226.50 would have no association with Malawi except perhaps by a common suffix or prefix in the variable names. Another option would be to combine all the data into a single stringā€”with the disadvantage that to work with each data element individually would require parsing it out. A final approach might be to create an anonymous type, but that, too, has limitations; enough, in fact, that tuples could potentially replace anonymous types entirely. Iā€™ll leave this topic until the end of the article.

The best option might be the C# 7.0 tuple, which, at its simplest, provides a syntax that allows you to combine the assignment of multiple variables, of varying types, in a single statement:

In this case, Iā€™m not only assigning multiple variables, but declaring them as well.

However, tuples have several other additional syntax possibilities, each shown in Figure 1 .

Figure 1 - Sample Code for Tuple Declaration and Assignment

In the first four examples, and although the right-hand side represents a tuple, the left-hand side still represents individual variables that are assigned together using tuple syntax , which involves two or more elements separated by commas and associated with parentheses. (I use the term tuple syntax because the underlying data type the compiler generates on the left-hand side isnā€™t technically a tuple.) The result is that although I start with values combined as a tuple on the right, the assignment to the left deconstructs the tuple into its constituent parts. In example 2, the left-hand-side assignment is to pre-declared variables. However, in examples 1, 3 and 4, the variables are declared within the tuple syntax. Given that Iā€™m only declaring variables, the naming and casing convention follows the generally accepted Framework Design Guidelinesā€”ā€œDo use camelCase for local variable names,ā€ for example.

Note that although implicit typing (var) can be distributed across each variable declaration within the tuple syntax, as shown in example 4, you canā€™t do the same with an explicit type (such as string). In this case, youā€™re actually declaring a tuple type, not just using tuple syntax and, therefore, youā€™ll need to add a reference to the System.ValueType NuGet packageā€”at least until .NET Standard 2.0. Because tuples allow each item to be a different data type, distributing the explicit type name across all elements wouldnā€™t necessarily work unless all the item data types were identical (and even then, the compiler doesnā€™t allow it).

In example 5, I declare a tuple on the left-hand side and then assign the tuple on the right. Note that the tuple has named itemsā€”names you can then reference to retrieve the item values back out of the tuple. This is what enables the countryInfo.Name, countryInfo.Capital, and countryInfo.GdpPerCapita syntax in the System.Console.WriteLine statement. The result of the tuple declaration on the left is a grouping of the variables into a single variable (countryInfo) from which you can then access the constituent parts. This is useful because you can then pass this single variable around to other methods and those methods will also be able to access the individual items within the tuple.

As already mentioned, variables defined using tuple syntax use camelCase. However, the convention for tuple item names isnā€™t well-defined. Suggestions include using parameter-naming conventions when the tuple behaves like a parameter ā€”such as when returning multiple values that before tuple syntax wouldā€™ve used out parameters. The alternative is to use PascalCase, following the naming convention for public fields and properties. I strongly favor the latter approach in accordance with the Capitalization Rules for Identifiers (itl.tc/caprfi). Tuple item names are rendered as members of the tuple and the convention for all (public) members (which are potentially accessed using a dot operator) is PascalCase.

Example 6 provides the same functionality as example 5, although it uses named tuple items on the right-hand side tuple value and an implicit type declaration on the left. The itemsā€™ names are persisted to the implicitly typed variable, however, so theyā€™re still available for the WriteLine statement. Of course, this opens the possibility that you could name the items on the left-hand side with names that are different from those you use on the right. While the C# compiler allows this, it will issue a warning that the item names on the right will be ignored as those on the left take precedence.

If no item names are specified, the individual elements are still available from the assigned tuple variable. However, the names are Item1, Item2 and so on, as shown in example 7. In fact, the ItemX name is always available on the tupleā€”even when custom names are provided (see example 8). However, when using IDE tools like any of the recent flavors of Visual Studio that support C# 7.0, the ItemX property will not appear within the IntelliSense dropdownā€”a good thing because presumably the provided name is preferable.

As shown in example 9, portions of a tuple assignment can be excluded using an underscore; this is called a discard.

Tuples are a lightweight solution for encapsulating data into a single object in the same way that a bag might capture miscellaneous items you pick up from the store. Unlike arrays, tuples contain item data types that can vary virtually without constraint (although pointers arenā€™t allowed), except that theyā€™re identified by the code and canā€™t be changed at run time. Also, unlike with arrays, the number of items within the tuple is hardcoded at compile time, as well. Last, you canā€™t add custom behavior to a tuple (extension methods notwithstanding). If you need behavior associated with the encapsulated data, then leveraging object-oriented programing and defining a class is the preferred approach.

The System.ValueTuple<ā€¦> Type

The C# compiler generates code that relies on a set of generic value types (structs), such as System.ValueTuple<T1, T2, T3>, as the underlying implementation for the tuple syntax for all tuple instances on the right-hand side of the examples in Figure 1 . Similarly, the same set of System.ValueTuple<...> generic value types is used for the left-hand-side data type starting with example 5. As youā€™d expect with a tuple type, the only methods included are those related to comparison and equality. However, perhaps unexpectedly, there are no properties for ItemX, but rather read-write fields (seemingly breaking the most basic of .NET Programming Guidelines as explained at itl.tc/CS7TuplesBreaksGuidelines ).

In addition to the programming guidelines discrepancy, thereā€™s another behavioral question that arises. Given that the custom item names and their types arenā€™t included in the System.ValueTuple<...> definition, how is it possible that each custom item name is seemingly a member of the System.ValueTuple<...> type and accessible as a member of that type?

Whatā€™s surprising (particularly for those familiar with the anonymous type implementation) is that the compiler doesnā€™t generate underlying Common Intermediate Language (CIL) code for the members corresponding to the custom names. However, even without an underlying member with the custom name, there is (seemingly) from the C# perspective, such a member.

For all the named tuple local variable examples, for example:

itā€™s clearly possible that the names could be known by the compiler for the remainder of the scope of the tuple because that scope is bounded within the member in which itā€™s declared. And, in fact, the compiler (and IDE) quite simply rely on this scope to allow accessing each item by name. In other words, the compiler looks at the item names within the tuple declaration and leverages them to allow code that uses those names within the scope. Itā€™s for this reason, as well, that the ItemX methods arenā€™t shown in the IDE IntelliSense as available members on the tuple (the IDE simply ignores them and replaces them with the named items).

Determining the item names from when scoped within a member is reasonable for the compiler, but what happens when a tuple is exposed outside the memberā€”such as a parameter or return from a method thatā€™s in a different assembly (for which thereā€™s possibly no source code available)? For all tuples that are part of the API (whether a public or private API), the compiler adds item names to the metadata of the member in the form of attributes. For example, this:

is the C# equivalent of what the compiler generates for the following:

On a related note, C# 7.0 doesnā€™t enable the use of custom item names when using the explicit System.ValueTuple<ā€¦> data type. Therefore, if you replace var in Example 8 of Figure 1 , youā€™ll end up with warnings that each item name will be ignored.

Here are a few additional miscellaneous facts to keep in mind about System.ValueTuple<ā€¦>:

  • There are a total of eight generic System.ValueTuple structs corresponding to the possibility of supporting a tuple with up to seven items. For the eighth tuple, System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>, the last type parameter allows specifying an additional value tuple, thus enabling support for n items. If, for example, you specify a tuple with 8 parameters, the compiler will automatically generate a System.ValueTuple<T1, T2, T3, T4, T5, T6, T7, System.ValueTuple<TSub1>> as the underlying implementing type. (For completeness, System.Value<T1> exists, but will really only be used directly and only as a type. It will never be used directly by the compiler because the C# tuple syntax requires a minimum of two items.)
  • There is a non-generic System.ValueTuple that serves as a tuple factory with Create methods corresponding to each value tuple arity. The ease of using a tuple literal, such as var t1 = (ā€œInigo Montoyaā€, 42), supersedes the Create method at least for C# 7.0 (or later) programmers.
  • For all practical purposes, C# developers can essentially ignore System.ValueTuple and System.ValueTuple<T>.

Thereā€™s another tuple type that was included with the .NET Framework 4.5ā€”System.Tuple<ā€¦>. At that time, it was expected to be the core tuple implementation going forward. However, once C# supported tuple syntax, it was realized that a value type generally performed better and so System.ValueTuple<ā€¦> was introduced, effectively replacing System.Tuple<ā€¦> in all cases except for backward compatibility with existing APIs that depend on System.Tuple<ā€¦>.

Wrapping Up

What many folks didnā€™t realize when it was first introduced is that the new C# 7.0 tuple all but replaces anonymous typesā€”and provides additional functionality. Tuples can be returned from methods, for example, and the item names are persisted in the API such that meaningful names can be used in place of ItemX type naming. And, like anonymous types, tuples can even represent complex hierarchical structures such as those that might be constructed in more complex LINQ queries (albeit, like with anonymous types, developers should do this with caution). That said, this could possibly lead to situations where the tuple value type exceeds 128 bytes and, therefore, might be a corner case for when to use anonymous types because itā€™s a reference type. Except for these corner cases (accessing via typical reflection might be another example), thereā€™s little to no reason to use an anonymous type when programming with C# 7.0 or later.

The ability to program with a tuple type object has been around for a long time (as mentioned, a tuple class, System.Tuple<ā€¦>, was introduced with the .NET Framework 4, but was available in Silverlight before that). However, these solutions never had an accompanying C# syntax, but rather nothing more than a .NET API. C# 7.0 brings a first-class tuple syntax that enables literalsā€”like var tuple = (42, ā€œInigo Montoyaā€)ā€”implicit typing, strong typing, public API utilization, integrated IDE support for named ItemX data and more. Admittedly, it might not be something you use in every C# file, but itā€™s likely something youā€™ll be grateful to have when the need arises and youā€™ll welcome the tuple syntax over the alternative out parameter or anonymous type.

Much of this article derives from my ā€œEssential C#ā€ book ( IntelliTect.com/EssentialCSharp ), which Iā€™m currently in the midst of updating to ā€œEssential C# 7.0.ā€ For more information on this topic, check out Chapter 3.

TUPLE ITEM NAMING GUIDELINES

Do use camelCase for all variables declared using tuple syntax.

Consider using PascalCase for all tuple item names.

Mark Michaelis Ā  is founder of IntelliTect, where he serves as its chief technical architect and trainer. For nearly two decades heā€™s been a Microsoft MVP, and a Microsoft Regional Director since 2007. Michaelis serves on several Microsoft software design review teams, including C#, Microsoft Azure, SharePoint and Visual Studio ALM. He speaks at developer conferences and has written numerous books, including his most recent, ā€œEssential C# 6.0 (5th Edition)ā€ ( itl.tc/EssentialCSharp ). Contact him on Facebook at facebook.com/Mark.Michaelis , on his blog at IntelliTect.com/Mark , on Twitter: @markmichaelis or via e-mail at [email protected] .

Thanks to the following Microsoft technical expert for reviewing this article: Mads Torgersen

Discuss this article in the MSDN Magazine forum

Additional resources

DEV Community

DEV Community

Rasheed K Mozaffar

Posted on Jul 28, 2023

C# Tuples: An Introductory Guide on Tuples in C# With Examples

Hey there šŸ‘‹šŸ».

We got an interesting topic today, and that is a quite unique data structure, that goes by the name Tuple .

So, what is a tuple? šŸ¤”

A tuple is a data structure used to group values that are related to each other into one object, it's often referred to as a single set of data, like a group of things that correlate to one another.

The definition is quite fuzzy and vague, but don't worry, we'll walk through everything you need to know to understand and start using tuples in C#.

Why tuples are useful šŸ¦¾

You know that a method in C#, or many other programming languages, could either return nothing, void in the case of our context, or return a value of some type that you the programmer decide on, it could be an int , double or even a user-defined type like an Employee . If we want our method to return multiple values to us, we could use out parameters , we could make our return type void , and use the out keyword and get those values from our method later, but forget about that, we can do better. šŸ¤“

Firstly, we look at how we can create and use tuples in C#, before moving on to seeing tuples as return types, and method parameters, so, Let's get going! šŸš€

How do we create a Tuple in C#? šŸ“

Tuples have a sort of unique syntax, but you can follow this blueprint as a template for creating tuples:

A code example could be:

Each value in the tuple is called an Item, and each Item has a number based on how they sequentially appear in order in the tuple, in the previous example, 1 is Item1 and 34 is Item2 and lastly Hello World! is Item3 .

We haven't provided names for our items, thus we get to access them using Item1 Item2 etc..., but we could give them names so that it's easier to access them instead of having a confusion trying to follow along items based off of their numbers, when you provide a name, you get to have two options, either access by the name, or the default Item, but it's more preferable to provide names to the values, like this:

How do we access items in a tuple

The syntax here is so simple, just use the name of your tuple, followed by a dot and then the item, like Item1 , Item2 , or, if you've given names for each item, you can use that instead, like the following:

Ok now that we got the basics out of the way, let's start using Tuples in some cool ways!

Let's build a method that performs primitive operations on two numbers šŸ§®

We'll see how we can use tuples, to return 4 different values from a method. Let's Go šŸš€ I want to write a method, that takes in two numbers of type double , and perform the essential arithmetic operations on, Addition, Subtraction, Multiplication & Division , I want my method to return the result of each operation on my numbers.

1: Create two double variables šŸ”¢ Simple enough, we need two numbers to work with, I'll go with these two:

2: Create the method that will do the operations šŸ“‘ Now here's where it gets interesting, the normal syntax to return maybe the sum of two numbers from a method, would be like this:

āš ļø Note: I'm assuming you're using a Console application, hence the use of the static keyword, since we want to call this method inside Main , which can only invoke static methods.

Enter our first tuple:

Ok, that's our tuple, notice we have a group of values to return, surrounded by parenthesis, that's the power of tuples, now when we return, we can return a whole bunch of values that we can later on access in a very elegant way, come on now, let's see how we can return them. Add the following code inside of the previously defined method OperateOnTwoNumbers

Isn't it pretty straightforward? In case you didn't catch up, I'll explain it to you. We're creating 4 new variables, each one corresponds to the operation we want to perform, after that, we're returning the result of each operation, bare in mind the initial order, like remember we had Addition, Subtraction... , when you return the values, we don't want to mix things up, and return the subtraction result as the multiplication.

āš ļø Note: We could've done the operations inside the return statement, but it would've looked terribly chaotic and lengthy.

3: Build a string to print the results to the console šŸ“Ÿ We now want to see the results in the console, we want to know if our operations did in fact work or not, we'll use the WriteLine() statement to format the result, just as follows:

You've now seen how we can return various values from a method, additionally, the values to return inside a tuple could be of any type you like, you can return a mix of Integers , Strings , Doubles or whichever type that fits the purpose!

Simple exercise āœļø

šŸ’” Can you think of a method that could make use of returning a group of values, in case you thought of any, write your own implementation and use tuples just like we've done, and post it down in the comments so I can see your work.

In case you haven't found any idea, why don't you try the following:

šŸ‘€ Can we create a method that takes in a bill, like any amount of money, say 50$, and returns values such as Tip Value, Date of Issuing, Sale Tax ? Those values could be arbitrary values, but try to implement that, and attempt creating a receipt-like output in the console!

We saw how we can return multiple values from a method, but guess what, we could also provide multiple parameters to a method, as one parameter only, using Tuples . Let's take a quick look.

Calculate the price of purchased fruits šŸšŸˆšŸŒ

Say I went to the market, and bought 5 Apples, 1 melon, and 10 Bananas, and I want to create a method, that takes the numbers of how many pieces of each fruit I bought, multiply the pieces by a price (Imaginary price defined within the method), and return to me the total I should pay.

To do that normally, we could create a method with 3 parameters, one for apples, one for melons, and one for bananas, but why do that when we can pass one tuple instead, let's see how:

The method is pretty much self-explanatory and doesn't require further simplification, if I now call it while passing in a tuple, I should get my total calculated:

After learning that, could we go back to the exercise I've given you, and instead of only returning the values as a tuple, change the input from the simple bill, to say different prices of dishes you've ordered at a restaurant, pass them as a tuple to the method, and return the Total, Sale Tax, Tip (Assume the tip is 7.5% of the total) , could we do that? And remember, show me your work in the comments section down below! šŸ—‚ļø

Top comments (0)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

thekarlesi profile image

How to Start Learning JavaScript

Karl Esi - May 6

xavier_script profile image

UNDERSTANDING UML DIAGRAMS BY IMPLEMENTING A MESSAGING APPLICATION

Onwuka David - Apr 22

wolffe profile image

Lighthouse Performance Tips & Tricks for Your Website

Ciprian Popescu - Apr 22

bytehide profile image

How to Use GitHub Copilot in Visual Studio 2024

ByteHide - Apr 22

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications

value-tuples.md

Latest commit, file metadata and controls, tuple types (c# reference).

The tuples feature provides concise syntax to group multiple data elements in a lightweight data structure. The following example shows how you can declare a tuple variable, initialize it, and access its data members:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="Introduction":::

As the preceding example shows, to define a tuple type, you specify types of all its data members and, optionally, the field names . You can't define methods in a tuple type, but you can use the methods provided by .NET, as the following example shows:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="MethodOnTuples":::

Tuple types support equality operators == and != . For more information, see the Tuple equality section.

Tuple types are value types ; tuple elements are public fields. That makes tuples mutable value types.

You can define tuples with an arbitrary large number of elements:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="LargeTuple":::

Use cases of tuples

One of the most common use cases of tuples is as a method return type. That is, instead of defining out method parameters , you can group method results in a tuple return type, as the following example shows:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="MultipleReturns":::

As the preceding example shows, you can work with the returned tuple instance directly or deconstruct it in separate variables.

You can also use tuple types instead of anonymous types ; for example, in LINQ queries. For more information, see Choosing between anonymous and tuple types .

Typically, you use tuples to group loosely related data elements. In public APIs, consider defining a class or a structure type.

Tuple field names

You explicitly specify tuple fields names in a tuple initialization expression or in the definition of a tuple type, as the following example shows:

[!code-csharp-interactive explicit field names ]

If you don't specify a field name, it may be inferred from the name of the corresponding variable in a tuple initialization expression, as the following example shows:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="InferFieldNames":::

That's called tuple projection initializers. The name of a variable isn't projected onto a tuple field name in the following cases:

  • The candidate name is a member name of a tuple type, for example, Item3 , ToString , or Rest .
  • The candidate name is a duplicate of another tuple field name, either explicit or implicit.

In the preceding cases, you either explicitly specify the name of a field or access a field by its default name.

The default names of tuple fields are Item1 , Item2 , Item3 and so on. You can always use the default name of a field, even when a field name is specified explicitly or inferred, as the following example shows:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="DefaultFieldNames":::

Tuple assignment and tuple equality comparisons don't take field names into account.

At compile time, the compiler replaces non-default field names with the corresponding default names. As a result, explicitly specified or inferred field names aren't available at run time.

Enable .NET code style rule IDE0037 to set a preference on inferred or explicit tuple field names.

Beginning with C# 12, you can specify an alias for a tuple type with a using directive . The following example adds a global using alias for a tuple type with two integer values for an allowed Min and Max value:

:::code language="csharp" source="snippets/shared/ValueTuples.cs" id="AliasTupleType":::

After declaring the alias, you can use the BandPass name as an alias for that tuple type:

:::code language="csharp" source="snippets/shared/ValueTuples.cs" id="UseAliasType":::

An alias doesn't introduce a new type , but only creates a synonym for an existing type. You can deconstruct a tuple declared with the BandPass alias the same as you can with its underlying tuple type:

:::code language="csharp" source="snippets/shared/ValueTuples.cs" id="DeconstructAlias":::

As with tuple assignment or deconstruction, the tuple member names don't need to match; the types do.

Similarly, a second alias with the same arity and member types can be used interchangeably with the original alias. You could declare a second alias:

:::code language="csharp" source="snippets/shared/ValueTuples.cs" id="AliasSynonym":::

You can assign a Range tuple to a BandPass tuple. As with all tuple assignment, the field names need not match, only the types and the arity.

:::code language="csharp" source="snippets/shared/ValueTuples.cs" id="AliasSynonymUses":::

An alias for a tuple type provides more semantic information when you use tuples. It doesn't introduce a new type. To provide type safety, you should declare a positional record instead.

Tuple assignment and deconstruction

C# supports assignment between tuple types that satisfy both of the following conditions:

  • both tuple types have the same number of elements
  • for each tuple position, the type of the right-hand tuple element is the same as or implicitly convertible to the type of the corresponding left-hand tuple element

Tuple element values are assigned following the order of tuple elements. The names of tuple fields are ignored and not assigned, as the following example shows:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="Assignment":::

You can also use the assignment operator = to deconstruct a tuple instance in separate variables. You can do that in many ways:

Use the var keyword outside the parentheses to declare implicitly typed variables and let the compiler infer their types:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="DeconstructVar":::

Explicitly declare the type of each variable inside parentheses:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="DeconstructExplicit":::

Declare some types explicitly and other types implicitly (with var ) inside the parentheses:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="DeconstructMixed":::

Use existing variables:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="DeconstructExisting":::

The destination of a deconstruct expression can include both existing variables and variables declared in the deconstruction declaration.

You can also combine deconstruction with pattern matching to inspect the characteristics of fields in a tuple. The following example loops through several integers and prints those that are divisible by 3. It deconstructs the tuple result of xref:System.Int32.DivRem%2A?displayProperty=nameWithType and matches against a Remainder of 0:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="DeconstructToPattern":::

For more information about deconstruction of tuples and other types, see Deconstructing tuples and other types .

Tuple equality

Tuple types support the == and != operators. These operators compare members of the left-hand operand with the corresponding members of the right-hand operand following the order of tuple elements.

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="TupleEquality":::

As the preceding example shows, the == and != operations don't take into account tuple field names.

Two tuples are comparable when both of the following conditions are satisfied:

  • Both tuples have the same number of elements. For example, t1 != t2 doesn't compile if t1 and t2 have different numbers of elements.
  • For each tuple position, the corresponding elements from the left-hand and right-hand tuple operands are comparable with the == and != operators. For example, (1, (2, 3)) == ((1, 2), 3) doesn't compile because 1 isn't comparable with (1, 2) .

The == and != operators compare tuples in short-circuiting way. That is, an operation stops as soon as it meets a pair of non equal elements or reaches the ends of tuples. However, before any comparison, all tuple elements are evaluated, as the following example shows:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="TupleEvaluationForEquality":::

Tuples as out parameters

Typically, you refactor a method that has out parameters into a method that returns a tuple. However, there are cases in which an out parameter can be of a tuple type. The following example shows how to work with tuples as out parameters:

:::code language="csharp" interactive="try-dotnet-method" source="snippets/shared/ValueTuples.cs" id="TupleAsOutParameter":::

Tuples vs System.Tuple

C# tuples, which are backed by xref:System.ValueTuple?displayProperty=nameWithType types, are different from tuples that are represented by xref:System.Tuple?displayProperty=nameWithType types. The main differences are as follows:

  • System.ValueTuple types are value types . System.Tuple types are reference types .
  • System.ValueTuple types are mutable. System.Tuple types are immutable.
  • Data members of System.ValueTuple types are fields. Data members of System.Tuple types are properties.

C# language specification

For more information, see:

  • Tuple types
  • Tuple equality operators
  • Value types
  • Choosing between anonymous and tuple types
  • xref:System.ValueTuple?displayProperty=nameWithType

Home Ā» C# Tutorial Ā» C# Tuples

Summary : in this tutorial, you’ll learn how to use C# tuples to represent a set of values as a single unit.

Introduction to the C# tuples

A tuple allows you to represent a set of values as a single unit. The type of tuples is System.ValueTuple .

Creating tuples & accessing elements

The following shows how to create a new tuple type:

In this example, we define a tuple named person with two fields. The first field is a string that represents the person’s name and the second field is an integer that represents the person’s age.

To access a field, you use the dot syntax:

Because fields of the person tuple have no names, C# assigns default field names to them as Item1 , Item2 , etc. For example:

To assign names to the fields of the tuple, you can use the following syntax:

In this example, we assign names to the fields of the person tuple and access their values via the field names.

Deconstructing tuple elements

Deconstructing a tuple means assigning elements of the tuple to multiple variables . To deconstruct elements of a tuple, you use the = operator. For example:

In this example, we assign the first and second elements of a tuple to the x and y variables.

You can also specify the types of variables explicitly when deconstructing a tuple:

Returning tuples

Tuples are useful when you want to return multiple values from a method. For example:

In this example, the method Calculate returns a named tuple with two elements: sum and product . When calling the method, we can assign the returned tuple to a variable result and access its elements using dot notation.

Note that you can deconstruct the tuple returned by the method like this:

Comparing Tuples

Tuples support the == and != operators. Two tuples are comparable when they comply with the following conditions:

  • Both tuples have the same number of elements.
  • The corresponding tuple elements are comparable using the == and != operators.

For example, the following example will result in an error because the number of elements is different:

The following example demonstrates that two tuples are equal:

System.ValueTuple vs. System.Tuple

So far, you have learned the tuples that belong to the System.ValueTuple type. They are completely different from tuples backed by the System.Tuple types.

The following table illustrates the main differences:

  • Use a tuple to represent a set of values as a single variable.
  • Do use tuples to make your code more readable and expressive.
  • Pattern Matching
  • Local Functions
  • Out Variable Declaration
  • Throw Expressions
  • Binary Literals
  • Digit Separators
  • Async Reutrn Types
  • Default Literal Expressions
  • Readonly References
  • Non-trailing Named Arguments
  • Private Protected
  • Conditional Ref Expressions
  • Unmanaged Generic Constraints
  • Indexing Fixed Fields Without Pinning
  • Fixed Pattern
  • Ref Returns and Ref Locals
  • Stackalloc Array Initializers
  • Tuple Equality and Inequality

C# 7 Tuples

Fastest entity framework extensions, what is a tuple.

A tuple provides a syntax that allows you to combine the assignment of multiple variables, of varying types, in a single statement.

  • It is a finite ordered list of values of different types, which combines related values without having to create a specific type to hold them.
  • It provides concise syntax to group multiple data elements in a lightweight data structure.

Why Tuples?

In C#, you can see a rich syntax for classes and structs that are used to explain your design intent, but sometimes that requires extra work with minimal benefit.

  • In many cases, you may have methods that return more than one variable, the traditional way is using the out parameter but there are some limitations for the out parameter such as, you can't use it with the async method.
  • To support these scenarios tuples were added to C#.

Before C# 7.1, a set of Tuple classes was already available in the .NET Framework. The following example shows how you can declare a tuple variable, initialize it, and access its data members.

In C# 7.1, a new feature is introduced to improve support for tuples. You can declare tuples types like anonymous types, except that tuples are not limited to the current method.

The following example shows the same example using the new feature.

As you can see that it becomes much cleaner and easy to read. To define a tuple type, you can specify types of all its data members as shown below.

Named Properties

You can assign names to the properties instead of having the default property names such as Item1 , Item2 etc.

You can also assign names on the right side with values as shown below.

You can provide names either on the left or right sides but not on both sides. The left side has precedence over the right side. The following will ignore names on the right side.

One of the most common use cases of tuples is to use as a method return type. You can group method results in a tuple return type instead of defining out method parameters as shown below.

Got any C# 7 Question?

logo rip

  • Advertise with us
  • Cookie Policy
  • Privacy Policy

Get monthly updates about new articles, cheatsheets, and tricks.

c# multiple assignment tuple

Dot Net Tutorials

Splitting Tuples in C# 7

Back to: C#.NET Tutorials For Beginners and Professionals

Splitting Tuples in C# 7 with Examples

In this article, I am going to discuss Splitting Tuples in C# 7 with Examples. Please read our previous article before proceeding to this article where we discussed Tuples in C# 7 with Examples. The Splitting Tuples in C# is a process of Splitting a Variable Value into Multiple Parts and storing each part into a new variable. This is very useful when you are working with Tuples in C# as we know Tuples are going to store multiple values.Ā 

Why do we need to Split Tuples in C#?

As we already discussed Tuples provides a lightweight way to retrieve multiple values from a method call. Once you retrieve the tuple, then you need to handle its individual elements. Handling these elements one by one is really a dirty approach. We can overcome this by splitting the Tuples in C#.

Example to Understand Splitting Tuples in C# 7

Letā€™s understand Splitting Tuples in C# with an example. Please have a look at the below example. As you can see in the below code, we are using Tuples to return four values from the GetEmployeeDetails method. And further, if you notice within the Main method, we are storing each value of the Tuple in separate variables. The following example code is self-explained, so please go through the comment lines for a better understanding.

When you run the application, you will get the data as expected as shown below.

Splitting Tuples in C#

As shown in the above example the GetEmployeeDetails() method returns a tuple with 4 values and then we assigned each of its elements to a variable in a separate operation. But from C# 7.0, now we can retrieve multiple elements from a tuple or retrieve multiple fields or property values from a Tuple in a single operation which is called Splitting Tuples in C# .

Different Ways to Deconstruct a Tuple or Splitting Tuples in C# 7:

We can explicitly declare the type of each field inside the parentheses. Letā€™s modify the program as shown below to understand this concept. The following example code is self-explained, so please go through the comment lines for a better understanding.

The above example deconstructs the 4-tuple returned by the GetEmployeeDetails() method explicitly by declaring the types of each filed within the parenthesis.

You can also use the var keyword so that C# infers the type of each variable. You can place the var keyword outside of the parentheses. Let us understand this by modifying the code as shown below. The following example code is self-explained, so please go through the comment lines for a better understanding.

The above example uses type inference when deconstructing the 4-tuple returned by the GetEmployeeDetails method.Ā  You can also use the var keyword individually with any or all of the variable declarations inside the parentheses. For a better understanding, please have a look at the below example.

Note: This method is cumbersome and is not recommended.

You may deconstruct the tuple into variables that have already been declared. For a better understanding, please have a look at the below example.

Points to Remember while Splitting Tuples in C# 7:

Note that you cannot specify a specific type outside the parentheses even if every field in the tuple has the same type. This generates compiler error CS8136, “Deconstruction ‘var (…)’ form disallows a specific type for ‘var’.”.

Note that you must assign each element of the tuple to a variable. If you omit any elements, the compiler generates error CS8132, “Cannot deconstruct a tuple of ‘x’ elements into ‘y’ variables.”

You cannot mix declarations and assignments to existing variables on the left-hand side of a deconstruction. The compiler generates error CS8184, “a deconstruction cannot mix declarations and expressions on the left-hand side.” when the members include newly declared and existing variables.

In the next article, I am going to discuss the Ā  Local Functions in C# 7 with Examples. Here, in this article, I try to explain Splitting Tuples in C# 7 with Examples. I hope you enjoy this Splitting Tuple in C# 7 with Examples article.

dotnettutorials 1280x720

About the Author: Pranaya Rout

Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

MAKOLYTE

Solve real coding problems

C# ā€“ How to use named tuples

You can use tuples to contain multiple values and pass them around. By default, the tuple field names are unfriendly ā€“ Item1, Item2, etcā€¦ Instead of using these default names, you can name the tuple fields. Hereā€™s an example of creating and using a named tuple:

Meaningful names makes tuples easier to use. movieTuple.title is easier to understand and use than movieTuple.Item1 . Behind the scenes, this is creating a ValueTuple<string, int> object. It has two fields: string Item1 and string Item2 . Naming the fields title and year doesnā€™t change the underlying field names. It just lets you refer to the fields with the friendly names while coding.

Iā€™ll show more examples of using named tuples.

Create a named tuple

There are three main ways to create a named tuple and give it values:

  • Declare the fields and assign the values at the same time (the field types are inferred):
  • Declare the tuple field names and types, then assign values to each field individually:
  • Declare the tuple field names and types, then assign values to all the fields at once ( deconstruction assignment ):

Return a named tuple from a method

You can return a named tuple from a method. This is a practical alternative to returning multiple out parameters. Hereā€™s an example:

The caller has access to the named fields:

Named tuple as method parameter

You can use a named tuple as a method parameter. Hereā€™s an example:

To call the method, create and pass in a tuple:

The caller isnā€™t required to pass in a named tuple. Just the tuple field types need to match (string, int). Hereā€™s an example:

Related Articles

  • C# ā€“ How to deconstruct tuples
  • C# ā€“ Using a dictionary with tuples
  • C# ā€“ Using a list of tuples
  • C# ā€“ Serialize a tuple to JSON

Leave a Comment Cancel reply

Grant Winney

Using Tuples and deconstruction to return multiple values in C#

A big challenge with any language is trying to group and organize things sensibly, and returning multiple values is no exception. Let's check out Tuples and deconstruction, and see how they can help us out.

One of the biggie challenges when programming in any language is figuring how to group and organize things sensibly. Even a small project can get out of hand quickly, and once you've got a dozen devs working in something for years, all bets are off.

So we have methods and functions, organized into classes (even JS has classes now) and namespaces, separate projects and assemblies, and on and on. The tricky part of having so many ways to organize things is knowing how and when to use one of them. A lot of it's up for debate (what isn't?) and some of it's not... I wouldn't recommend publishing a NuGet package for a few lines of code , lol.

In C#, it's not uncommon to use classes to group similar logic together, and then provide properties to access whatever values are in the class - a person with a name and birthdate, a car with an engine type and model, whatever. If you're going to have lots of properties, a class probably makes sense. But what if you don't? If there's a more lightweight option than a class and a good use case for it, I'd be interested in hearing about it.. or writing about it as the case may be.

One alternative is to create a method with several "out" parameters.

I used to think that was ugly since we had to define the variables before calling the method, but now they can be defined right as we call the method so it's a lot more palatable. That was introduced in C# 7.0 .

Another alternative, and the one I want to really focus on, is using tuples. I used to like them even less than "out" parameters, since whatever values you returned were only accessible by referencing .Item1 , .Item2 , etc. You immediately lost context of what was being returned.. very unfriendly. There have been some major changes though since C# 7.0 , and it makes tuples much easier on the eyes.. brain... something. They're easier to work with.

Here's an example that's pretty similar to the one above using "out" parameters, but it returns a tuple type instead. Since tuple types can have field names too, this really seems to behave more like a class to me.

Being able to access each element of the tuple by name makes this soo much friendlier than in the past.

You can desconstruct a tuple if you'd like, assigning all the elements in one place, which is similar to how the "out" example works.

And if you don't need all of the elements, you can even discard them . Here's an example where all I needed was the area of the circle, so I discarded the rest.

As usual, all the above code snippets are on GitHub, so grab the code if you'd to play around with it more on your own. What do you think? Like it more than classes and "out" variables? Love it? Hate it? Or do you have your own way of returning multiple values at once?

If you found this content useful, and want to learn more about a variety of C# features, check out this GitHub repo , where you'll find links to plenty more blog posts and practical examples!

c# multiple assignment tuple

How to use TimeProvider and FakeTimeProvider (time abstraction in .NET)

What are generic attributes in c# 11, how to log messages to multiple targets with nlog.

IMAGES

  1. C# Tuple: How to work with a Tuples in C#?

    c# multiple assignment tuple

  2. How to use Tuple elements in C# (C Sharp)

    c# multiple assignment tuple

  3. How to work with a Tuple in C#

    c# multiple assignment tuple

  4. C# Tuple with Examples

    c# multiple assignment tuple

  5. Let's Show #143

    c# multiple assignment tuple

  6. [Tuples and Dictionaries] Tuple Assignment

    c# multiple assignment tuple

VIDEO

  1. Tuple in c#

  2. TechTutorialz: Interfaces in C# , Multiple Inheritance, Multi Level Inheritance

  3. Assignment 1 PRN221

  4. Assignment final C#

  5. VARIABLES & MULTIPLE ASSIGNMENT

  6. C# 105 : Tuple in C# 7 in Telugu

COMMENTS

  1. c#

    Valid up to C# 6: No, this is not possible. There's no such language feature in C#. If you think the following code: string firstValue = tupleWithTwoValues.Item1; string secondValue = tupleWithTwoValues.Item2; is ugly, then you should reconsider using tuples at the first place.

  2. Tuple types

    The tuples feature provides concise syntax to group multiple data elements in a lightweight data structure. The following example shows how you can declare a tuple variable, initialize it, and access its data members: C#. Copy. Run. (double, int) t1 = (4.5, 3); Console.WriteLine($"Tuple with elements {t1.Item1} and {t1.Item2}.");

  3. C# Tuples as Syntactic Sugar for Multiple Variable Assignment

    The normal way that you consume tuples as return types is to create the variables in the expression: private static (double, double, int) ComputeSumAndSumOfSquares(IEnumerable<double> sequence) {. // method body omitted. } // you can explicitly declare the types of each field. ( int count, double sum, double sumOfSquares ...

  4. Deconstructing tuples and other types

    Retrieving multiple field and property values from an object can be equally cumbersome: you must assign a field or property value to a variable on a member-by-member basis. You can retrieve multiple elements from a tuple or retrieve multiple field, property, and computed values from an object in a single deconstruct operation. To deconstruct a ...

  5. Essential .NET

    The best option might be the C# 7.0 tuple, which, at its simplest, provides a syntax that allows you to combine the assignment of multiple variables, of varying types, in a single statement: C#. Copy. (string country, string capital, double gdpPerCapita) =. ("Malawi", "Lilongwe", 226.50); In this case, I'm not only assigning multiple ...

  6. C# Tuples: An Introductory Guide on Tuples in C# With Examples

    1: Create two double variables šŸ”¢. Simple enough, we need two numbers to work with, I'll go with these two: double first = 5; double second = 10; 2: Create the method that will do the operations šŸ“‘. Now here's where it gets interesting, the normal syntax to return maybe the sum of two numbers from a method, would be like this:

  7. Tuple types (C# reference)

    The tuples feature provides concise syntax to group multiple data elements in a lightweight data structure. The following example shows how you can declare a tuple variable, initialize it, and access its data members: ... C# supports assignment between tuple types that satisfy both of the following conditions:

  8. Using Tuples in C# to Initialize Properties in the Constructor and to

    Since C# 7.0 you can use tuples in your code and you can also use expression bodied constructors. These two features allow you to write constructors in a more compact syntax that you see above. ... As you've seen in this blog post, tuples are quite powerful to combine multiple assign statements into a single statement. And by combining tuples ...

  9. C# Tuples

    In this example, we assign names to the fields of the person tuple and access their values via the field names. Deconstructing tuple elements. Deconstructing a tuple means assigning elements of the tuple to multiple variables. To deconstruct elements of a tuple, you use the = operator. For example:

  10. Tuples in C# 7 with Real-time Examples

    Tuples Before C# 7: In the following example, we are returning two values (integer and double) from the Calculate method using the Tuple class. Here, within the Calculate method, we create an instance of the Tuple class by calling the static Create method of the Tuple class. To the static Create method, we are passing the required integer and ...

  11. Tuples and unpacking assignment support in C#?

    An extension might get it closer to Python tuple unpacking, not more efficient but more readable (and Pythonic): public class Extensions { public static void UnpackTo<T1, T2>(this Tuple<T1, T2> t, out T1 v1, out T2 v2) { v1 = t.Item1; v2 = t.Item2; } } Tuple<int, int> MyMethod() { // some work to find row and col return Tuple.Create(row, col); } int row, col; MyMethod().UnpackTo(out row, out ...

  12. c#

    The logic is as follows: The assignment operation itself returns a value, which is the value that has been assigned. The sequence of execution is: num1 = (num2 = 5) and the first assignment which is executed ( num2 = 5) returns the value 5 to the outside world - which is in turn assigned to num1. This works ad infinitum ( num0 = num1 = num2 = 5 ...

  13. C# 7

    A tuple provides a syntax that allows you to combine the assignment of multiple variables, of varying types, in a single statement. ... To support these scenarios tuples were added to C#. Before C# 7.1, a set of Tuple classes was already available in the .NET Framework. The following example shows how you can declare a tuple variable ...

  14. Deep Dive Into C# Tuple Types

    So one great use of tuple might be returning multiple values from a method. ... Tuple Assignment. C# has a build-in mechanism to assign tuple values (right hand) to tuple elements (left hand). ...

  15. 9 Composition using tuples Ā· C# in Depth, Fourth Edition

    Tuples let us perform a single assignment which changes both elements. Of course the temporary variable is still there - in this case we end up with an extra temporary variable, although I doubt you'd ever notice any performance difference. ... That mapping is pretty obvious when the C# tuple type doesn't have any element names: (int ...

  16. Splitting Tuples in C# 7 with Examples

    Back to: C#.NET Tutorials For Beginners and Professionals Splitting Tuples in C# 7 with Examples. In this article, I am going to discuss Splitting Tuples in C# 7 with Examples. Please read our previous article before proceeding to this article where we discussed Tuples in C# 7 with Examples. The Splitting Tuples in C# is a process of Splitting a Variable Value into Multiple Parts and storing ...

  17. c#

    If I assign aforementioned objects like this below, am I actually using a tuple as the left operand, or is it just a syntactic sugar for assigning? Well, according to the draft PR that will standardize deconstructing assignment it is a "tuple expression" - but that doesn't mean it creates a tuple value.

  18. C#

    //Define structure (string title, int year) movie; //Assign all variables at once using deconstruction assignment movie = ("The Matrix", 1999); Code language: C# (cs) Return a named tuple from a method. You can return a named tuple from a method. This is a practical alternative to returning multiple out parameters. Here's an example:

  19. Using Tuples and deconstruction to return multiple values in C#

    You can desconstruct a tuple if you'd like, assigning all the elements in one place, which is similar to how the "out" example works. // Deconstruct the tuple elements into separate local variables var ( diameter, circumference, area) = GetCircle(4); Console.WriteLine($"Diameter: {diameter}"); // 8.

  20. How does tuple assignment work in C# when swapping variables?

    How does the tuple assignment work so that no values are lost? // Old way. var tmp = n; n = m; m = tmp; // Tuple assignment (n, m) = (m, n); Both ways produce the same result. Is this dealt with as a special case in the tuple class, or is it a byproduct of the way this class is generally implemented?

  21. Working With Tuples In C#

    In simple words, Tuples is a variable that can contain multiple variables of different data types. Console.WriteLine($"Tuple elements { tuple1.Item1} and { tuple1.Item2}."); In the above line of code you can see that tuple1 contains a double and int. Let's update the above code. As you can see we have added a string in tuple.