Select is a LINQ projection method: it creates one output element from each input element. Use it when a sequence contains more information than the result needs. For example, reflection returns PropertyInfo objects for a type’s properties, but a service listing available fonts needs only their names. section 3.1.1 section 5.2
Listing 3.9 LINQ query translated to methods
public static Lazy<IEnumerable<string>> AllFonts =
new (() =>
typeof(FiggleFonts) #1
.GetProperties(
BindingFlags.Public | BindingFlags.Static)
.Select(p => p.Name)); #2
GetProperties supplies the input sequence. Select(p => p.Name) reads each property’s Name and produces a sequence of strings. The lambda states what to keep; it does not change the PropertyInfo objects. section 3.1.1
The same projection can be written with LINQ query syntax: from p in the properties select p.Name. The C# compiler translates that form into a method call like Select(p => p.Name). Choose the form that makes the surrounding query clearest. section 3.1.1
Listing 3.13 Modifying AllFonts to return a tuple
public static
Lazy<IEnumerable<(string Name, FiggleFont Font)>> #1
AllFonts = new (() =>
from p in typeof(FiggleFonts)
.GetProperties(
BindingFlags.Public | BindingFlags.Static)
select ( #1
Name: p.Name, #2
Font: (p.GetValue(null) as FiggleFont) #3
));
A projection need not return a single property. Selecting a tuple containing a property name and its FiggleFont value keeps both available for later filtering and sorting. This changes the output element type from string to a named tuple. section 3.1.1
Select also belongs in longer LINQ pipelines. Where restricts elements, Skip and Take partition a sequence, and ordering methods sort it; Select determines the shape of each output element. LINQ applies to enumerable collections and also includes queryable collections used with EF Core. section 3.1.1 section 5.2

