HOWTO · Csharp

How to Initialize a List of Tuples in C#

This article explores several approaches to efficiently initialize a list of tuples in C#.

On this page

To initialize a list of tuples in C#, choose between List<Tuple<int, string>> for reference tuples and List<(int, string)> for value tuples. You can create the entries in a collection initializer, append them with Add(), or project an existing sequence with LINQ. These tuple types are distinct, so choose the one that matches the types used by the rest of your code.

Initialize a List of Tuples in C# Using the Tuple.Create() Method

Tuple.Create() creates a reference tuple. A collection initializer lets you create several entries as you declare a List<Tuple<int, string>>:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var tupleList = new List<Tuple<int, string>>
        {
            Tuple.Create(1, "Apple"),
            Tuple.Create(2, "Banana"),
            Tuple.Create(3, "Cherry")
        };

        foreach (var tuple in tupleList)
        {
            Console.WriteLine(tuple);
        }
    }
}

The generic list type records the tuple element types: an int followed by a string. Tuple.Create() infers those types from each pair of values, and the loop visits the entries in their insertion order. See the Tuple.Create() method documentation for its overloads.

Initialize a List of Tuples in C# Using the () Notation

A list can also contain value tuples, written with the () notation. This example uses List<(int, string)> and initializes three entries directly:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var tupleList = new List<(int, string)>
        {
            (1, "Apple"),
            (2, "Banana"),
            (3, "Cherry")
        };

        foreach (var tuple in tupleList)
        {
            Console.WriteLine(tuple);
        }
    }
}

Here, (int, string) is the value-tuple element type, and each parenthesized pair supplies one list item. The same pairs can be represented with a different list element type. Read more about value tuples in C#.

Initialize a List of Tuples in C# Using List<Tuple<T1, T2>> and Add()

Use Add() when entries arrive over time or when the list is assembled through application logic. Start with an empty list, then append each reference tuple:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var tupleList = new List<Tuple<int, string>>();

        tupleList.Add(Tuple.Create(1, "Apple"));
        tupleList.Add(Tuple.Create(2, "Banana"));
        tupleList.Add(Tuple.Create(3, "Cherry"));

        foreach (var tuple in tupleList)
        {
            Console.WriteLine(tuple);
        }
    }
}

The list’s declared type determines the kind of tuple it stores. Each Add() call appends one Tuple<int, string>; Tuple.Create() constructs that reference tuple from the supplied values.

Initialize a List of Tuples in C# Using LINQ

LINQ is useful when the tuple entries come from an existing sequence. Select() projects each number into a tuple, and ToList() materializes the projected sequence as a list:

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        var tupleList = Enumerable.Range(1, 3)
            .Select(i => Tuple.Create(i, $"Fruit{i}"))
            .ToList();

        foreach (var tuple in tupleList)
        {
            Console.WriteLine(tuple);
        }
    }
}

Enumerable.Range(1, 3) supplies 1, 2, and 3. The projection pairs each number with a string, and ToList() returns a List<Tuple<int, string>>. Because the projection uses Tuple.Create(), these are reference tuples.

Conclusion

For a fixed set of values, a collection initializer is concise with either Tuple.Create() or value-tuple literals. Use Add() to build a List<Tuple<T1, T2>> incrementally, and use LINQ when converting an existing sequence into tuple entries. Reference tuples (Tuple<T1, T2>) and value tuples ((T1, T2)) are different types; keep the chosen type consistent with the APIs and data your code uses.