SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T> ,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T> ,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。 每个源元素的索引用于该元素的中间投影表。

SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。 每个源元素的索引用于该元素的投影表。

public:
generic <typename TSource, typename TCollection, typename TResult>
[System::Runtime::CompilerServices::Extension]
 static System::Collections::Generic::IEnumerable<TResult> ^ SelectMany(System::Collections::Generic::IEnumerable<TSource> ^ source, Func<TSource, System::Collections::Generic::IEnumerable<TCollection> ^> ^ collectionSelector, Func<TSource, TCollection, TResult> ^ resultSelector);
public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TCollection,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,System.Collections.Generic.IEnumerable<TCollection>> collectionSelector, Func<TSource,TCollection,TResult> resultSelector);
static member SelectMany : seq<'Source> * Func<'Source, seq<'Collection>> * Func<'Source, 'Collection, 'Result> -> seq<'Result>
<Extension()>
Public Function SelectMany(Of TSource, TCollection, TResult) (source As IEnumerable(Of TSource), collectionSelector As Func(Of TSource, IEnumerable(Of TCollection)), resultSelector As Func(Of TSource, TCollection, TResult)) As IEnumerable(Of TResult)
TSource

下面的代码示例演示如何使用 SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) 对数组执行一对多投影,并使用结果选择器函数将源序列中的每个对应元素保留在对 的最后调用 Select 的范围内。

class PetOwner public string Name { get; set; } public List<string> Pets { get; set; } public static void SelectManyEx3() PetOwner[] petOwners = { new PetOwner { Name="Higa", Pets = new List<string>{ "Scruffy", "Sam" } }, new PetOwner { Name="Ashkenazi", Pets = new List<string>{ "Walker", "Sugar" } }, new PetOwner { Name="Price", Pets = new List<string>{ "Scratches", "Diesel" } }, new PetOwner { Name="Hines", Pets = new List<string>{ "Dusty" } } }; // Project the pet owner's name and the pet's name. var query = petOwners .SelectMany(petOwner => petOwner.Pets, (petOwner, petName) => new { petOwner, petName }) .Where(ownerAndPet => ownerAndPet.petName.StartsWith("S")) .Select(ownerAndPet => Owner = ownerAndPet.petOwner.Name, Pet = ownerAndPet.petName // Print the results. foreach (var obj in query) Console.WriteLine(obj); // This code produces the following output: // {Owner=Higa, Pet=Scruffy} // {Owner=Higa, Pet=Sam} // {Owner=Ashkenazi, Pet=Sugar} // {Owner=Price, Pet=Scratches} Structure PetOwner Public Name As String Public Pets() As String End Structure Sub SelectManyEx3() ' Create an array of PetOwner objects. Dim petOwners() As PetOwner = {New PetOwner With {.Name = "Higa", .Pets = New String() {"Scruffy", "Sam"}}, New PetOwner With {.Name = "Ashkenazi", .Pets = New String() {"Walker", "Sugar"}}, New PetOwner With {.Name = "Price", .Pets = New String() {"Scratches", "Diesel"}}, New PetOwner With {.Name = "Hines", .Pets = New String() {"Dusty"}}} ' Project an anonymous type that consists of ' the owner's name and the pet's name (string). Dim query = petOwners _ .SelectMany( Function(petOwner) petOwner.Pets, Function(petOwner, petName) New With {petOwner, petName}) _ .Where(Function(ownerAndPet) ownerAndPet.petName.StartsWith("S")) _ .Select(Function(ownerAndPet) _ New With {.Owner = ownerAndPet.petOwner.Name, .Pet = ownerAndPet.petName Dim output As New System.Text.StringBuilder For Each obj In query output.AppendLine(String.Format("Owner={0}, Pet={1}", obj.Owner, obj.Pet)) ' Display the output. Console.WriteLine(output.ToString()) End Sub ' This code produces the following output: ' Owner=Higa, Pet=Scruffy ' Owner=Higa, Pet=Sam ' Owner=Ashkenazi, Pet=Sugar ' Owner=Price, Pet=Scratches

此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用 GetEnumerator 其方法或在 C# For Each foreach Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) 当必须将 的 source 元素保留在调用 SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) 后发生的查询逻辑的范围内时,方法非常有用。 有关代码示例,请参见“示例”部分。 如果 类型的对象与 类型的 TSource 对象之间存在双向关系,即,如果 类型的 TCollection 对象提供属性来检索 TSource 生成它的 对象,则不需要 的此重载 SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) TCollection 。 相反,可以使用 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) 并通过 对象 TCollection 导航回 TSource 对象。

在查询表达式语法中,在初始子句转换为 调用 SelectMany 后,每个 from 子句 (C#) 或 From 子句 (Visual Basic) 。

public:
generic <typename TSource, typename TCollection, typename TResult>
[System::Runtime::CompilerServices::Extension]
 static System::Collections::Generic::IEnumerable<TResult> ^ SelectMany(System::Collections::Generic::IEnumerable<TSource> ^ source, Func<TSource, int, System::Collections::Generic::IEnumerable<TCollection> ^> ^ collectionSelector, Func<TSource, TCollection, TResult> ^ resultSelector);
public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TCollection,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,int,System.Collections.Generic.IEnumerable<TCollection>> collectionSelector, Func<TSource,TCollection,TResult> resultSelector);
static member SelectMany : seq<'Source> * Func<'Source, int, seq<'Collection>> * Func<'Source, 'Collection, 'Result> -> seq<'Result>
<Extension()>
Public Function SelectMany(Of TSource, TCollection, TResult) (source As IEnumerable(Of TSource), collectionSelector As Func(Of TSource, Integer, IEnumerable(Of TCollection)), resultSelector As Func(Of TSource, TCollection, TResult)) As IEnumerable(Of TResult)
TSource

此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用 GetEnumerator 其方法或在 C# For Each foreach Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) 当必须将 的 source 元素保留在调用 SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) 后发生的查询逻辑的范围内时,方法非常有用。 有关代码示例,请参见“示例”部分。 如果 类型的对象与 类型的 TSource 对象之间存在双向关系,即,如果 类型的 TCollection 对象提供属性来检索 TSource 生成它的 对象,则不需要 的此重载 SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) TCollection 。 相反,可以使用 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) 并通过 对象 TCollection 导航回 TSource 对象。

public:
generic <typename TSource, typename TResult>
[System::Runtime::CompilerServices::Extension]
 static System::Collections::Generic::IEnumerable<TResult> ^ SelectMany(System::Collections::Generic::IEnumerable<TSource> ^ source, Func<TSource, System::Collections::Generic::IEnumerable<TResult> ^> ^ selector);
public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,System.Collections.Generic.IEnumerable<TResult>> selector);
static member SelectMany : seq<'Source> * Func<'Source, seq<'Result>> -> seq<'Result>
<Extension()>
Public Function SelectMany(Of TSource, TResult) (source As IEnumerable(Of TSource), selector As Func(Of TSource, IEnumerable(Of TResult))) As IEnumerable(Of TResult)
TSource

下面的代码示例演示如何使用 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) 对数组执行一对多投影。

class PetOwner public string Name { get; set; } public List<String> Pets { get; set; } public static void SelectManyEx1() PetOwner[] petOwners = { new PetOwner { Name="Higa, Sidney", Pets = new List<string>{ "Scruffy", "Sam" } }, new PetOwner { Name="Ashkenazi, Ronen", Pets = new List<string>{ "Walker", "Sugar" } }, new PetOwner { Name="Price, Vernette", Pets = new List<string>{ "Scratches", "Diesel" } } }; // Query using SelectMany(). IEnumerable<string> query1 = petOwners.SelectMany(petOwner => petOwner.Pets); Console.WriteLine("Using SelectMany():"); // Only one foreach loop is required to iterate // through the results since it is a // one-dimensional collection. foreach (string pet in query1) Console.WriteLine(pet); // This code shows how to use Select() // instead of SelectMany(). IEnumerable<List<String>> query2 = petOwners.Select(petOwner => petOwner.Pets); Console.WriteLine("\nUsing Select():"); // Notice that two foreach loops are required to // iterate through the results // because the query returns a collection of arrays. foreach (List<String> petList in query2) foreach (string pet in petList) Console.WriteLine(pet); Console.WriteLine(); This code produces the following output: Using SelectMany(): Scruffy Walker Sugar Scratches Diesel Using Select(): Scruffy Walker Sugar Scratches Diesel Structure PetOwner Public Name As String Public Pets() As String End Structure Sub SelectManyEx1() ' Create an array of PetOwner objects. Dim petOwners() As PetOwner = {New PetOwner With {.Name = "Higa, Sidney", .Pets = New String() {"Scruffy", "Sam"}}, New PetOwner With {.Name = "Ashkenazi, Ronen", .Pets = New String() {"Walker", "Sugar"}}, New PetOwner With {.Name = "Price, Vernette", .Pets = New String() {"Scratches", "Diesel"}}} ' Call SelectMany() to gather all pets into a "flat" sequence. Dim query1 As IEnumerable(Of String) = petOwners.SelectMany(Function(petOwner) petOwner.Pets) Dim output As New System.Text.StringBuilder("Using SelectMany():" & vbCrLf) ' Only one foreach loop is required to iterate through ' the results because it is a one-dimensional collection. For Each pet As String In query1 output.AppendLine(pet) ' This code demonstrates how to use Select() instead ' of SelectMany() to get the same result. Dim query2 As IEnumerable(Of String()) = petOwners.Select(Function(petOwner) petOwner.Pets) output.AppendLine(vbCrLf & "Using Select():") ' Notice that two foreach loops are required to iterate through ' the results because the query returns a collection of arrays. For Each petArray() As String In query2 For Each pet As String In petArray output.AppendLine(pet) ' Display the output. Console.WriteLine(output.ToString()) End Sub ' This code produces the following output: ' Using SelectMany(): ' Scruffy ' Sam ' Walker ' Sugar ' Scratches ' Diesel ' Using Select(): ' Scruffy ' Sam ' Walker ' Sugar ' Scratches ' Diesel

此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用 GetEnumerator 其方法或在 C# For Each foreach Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。

方法 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) 枚举输入序列,使用转换函数将每个元素映射到 , IEnumerable<T> 然后枚举并生成每个此类 IEnumerable<T> 对象的元素。 也就是说,对于 的每个元素 source selector 将调用 并返回一系列值。 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) 然后,将此集合的二维集合平展为一维 IEnumerable<T> 并返回它。 例如,如果查询使用 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) 获取数据库中每个客户) 类型的 Order 订单 (,则结果的类型为 IEnumerable<Order> C# 或 IEnumerable(Of Order) Visual Basic。 如果查询改为使用 Select 来获取订单,则不会组合订单集合集合,并且结果的类型为 IEnumerable<List<Order>> C# 或 IEnumerable(Of List(Of Order)) Visual Basic。

在查询表达式语法中,在初始子句转换为 调用 SelectMany 后,每个 from 子句 (C#) 或 From 子句 (Visual Basic) 。

public:
generic <typename TSource, typename TResult>
[System::Runtime::CompilerServices::Extension]
 static System::Collections::Generic::IEnumerable<TResult> ^ SelectMany(System::Collections::Generic::IEnumerable<TSource> ^ source, Func<TSource, int, System::Collections::Generic::IEnumerable<TResult> ^> ^ selector);
public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,int,System.Collections.Generic.IEnumerable<TResult>> selector);
static member SelectMany : seq<'Source> * Func<'Source, int, seq<'Result>> -> seq<'Result>
<Extension()>
Public Function SelectMany(Of TSource, TResult) (source As IEnumerable(Of TSource), selector As Func(Of TSource, Integer, IEnumerable(Of TResult))) As IEnumerable(Of TResult)
TSource

下面的代码示例演示如何使用 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) 对数组执行一对多投影,并使用每个外部元素的索引。

class PetOwner public string Name { get; set; } public List<string> Pets { get; set; } public static void SelectManyEx2() PetOwner[] petOwners = { new PetOwner { Name="Higa, Sidney", Pets = new List<string>{ "Scruffy", "Sam" } }, new PetOwner { Name="Ashkenazi, Ronen", Pets = new List<string>{ "Walker", "Sugar" } }, new PetOwner { Name="Price, Vernette", Pets = new List<string>{ "Scratches", "Diesel" } }, new PetOwner { Name="Hines, Patrick", Pets = new List<string>{ "Dusty" } } }; // Project the items in the array by appending the index // of each PetOwner to each pet's name in that petOwner's // array of pets. IEnumerable<string> query = petOwners.SelectMany((petOwner, index) => petOwner.Pets.Select(pet => index + pet)); foreach (string pet in query) Console.WriteLine(pet); // This code produces the following output: // 0Scruffy // 0Sam // 1Walker // 1Sugar // 2Scratches // 2Diesel // 3Dusty Structure PetOwner Public Name As String Public Pets() As String End Structure Sub SelectManyEx2() ' Create an array of PetOwner objects. Dim petOwners() As PetOwner = {New PetOwner With {.Name = "Higa, Sidney", .Pets = New String() {"Scruffy", "Sam"}}, New PetOwner With {.Name = "Ashkenazi, Ronen", .Pets = New String() {"Walker", "Sugar"}}, New PetOwner With {.Name = "Price, Vernette", .Pets = New String() {"Scratches", "Diesel"}}, New PetOwner With {.Name = "Hines, Patrick", .Pets = New String() {"Dusty"}}} ' Project the items in the array by appending the index ' of each PetOwner to each pet's name in that petOwner's ' array of pets. Dim query As IEnumerable(Of String) = petOwners.SelectMany(Function(petOwner, index) _ petOwner.Pets.Select(Function(pet) _ index.ToString() + pet)) Dim output As New System.Text.StringBuilder For Each pet As String In query output.AppendLine(pet) ' Display the output. Console.WriteLine(output.ToString()) End Sub

此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用 GetEnumerator 其方法或在 C# For Each foreach Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。

方法 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) 枚举输入序列,使用转换函数将每个元素映射到 , IEnumerable<T> 然后枚举并生成每个此类 IEnumerable<T> 对象的元素。 也就是说,对于 的每个元素 source selector 将调用 并返回一系列值。 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) 然后,将此集合的二维集合平展为一维 IEnumerable<T> 并返回它。 例如,如果查询使用 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) 获取数据库中每个客户) 类型的 Order 订单 (,则结果的类型为 IEnumerable<Order> C# 或 IEnumerable(Of Order) Visual Basic。 如果查询改为使用 Select 来获取订单,则不会组合订单集合集合,并且结果的类型为 IEnumerable<List<Order>> C# 或 IEnumerable(Of List(Of Order)) Visual Basic。

第一个参数表示 selector 要处理的元素。 第二个参数表示 selector 源序列中该元素的从零开始的索引。 例如,如果元素采用已知顺序并且你想要对特定索引处的元素执行某些操作,则这非常有用。 如果要检索一个或多个元素的索引,它也很有用。