C# Projection
Projection reshapes each item in a sequence into a new form. Select makes one output per input, and SelectMany flattens nested sequences into one flat sequence.
Select to computed values
Select doubles each number. Each input number gives one doubled output number.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int> { 2, 3, 4 };
var doubled = numbers.Select(n => n * 2);
foreach (int n in doubled)
{
Console.WriteLine(n);
}
}
}Select into an anonymous shape
Select builds an anonymous value for each name. The value holds the name and its length.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string> { "Hana", "Bo", "Priya" };
var shaped = names.Select(name => new { Name = name, Length = name.Length });
foreach (var item in shaped)
{
Console.WriteLine(item.Name + ": " + item.Length);
}
}
}SelectMany flattens lists
SelectMany reads each inner list as part of one result. The numbers print in their original order.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
List<List<int>> grid = new List<List<int>>
{
new List<int> { 1, 2 },
new List<int> { 3 }
};
var flat = grid.SelectMany(row => row);
foreach (int n in flat)
{
Console.WriteLine(n);
}
}
}Example
using System;
using System.Collections.Generic;
using System.Linq;
class Person
{
public string Name = "";
public int Age;
}
class Program
{
static void Main(string[] args)
{
List<Person> people = new List<Person>
{
new Person { Name = "Hana", Age = 27 },
new Person { Name = "Bo", Age = 31 }
};
var shaped = people.Select(p => new { Name = p.Name, Age = p.Age });
foreach (var person in shaped)
{
Console.WriteLine(person);
}
}
}Key points
- Select takes a lambda that builds the new form of each item.
- The output sequence holds one item for each input item.
- An anonymous type is a compiler-made shape written as new { ... }.
- Anonymous properties are read from the value with dot syntax.
- Printing an anonymous value shows its shape as { Name = Hana, Age = 27 }.
- SelectMany takes a lambda that returns a sequence for each item.
- SelectMany merges those inner sequences into one sequence.
In this example, Select builds an anonymous value for each person. Each value copies the name and the age. Printing the value shows the anonymous shape with its property names and values.
Note
Select keeps the nesting, and SelectMany removes one level of it.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does SelectMany print for a list holding { 1, 2 } and { 3 }?