From 5132f4704c505176305c2fccb7911a423be23566 Mon Sep 17 00:00:00 2001 From: Mahmoud Bakir Date: Sun, 5 Apr 2026 15:47:03 +0530 Subject: [PATCH 01/10] Add AggregateBy seedSelector examples --- xml/System.Linq/Enumerable.xml | 93 +++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/xml/System.Linq/Enumerable.xml b/xml/System.Linq/Enumerable.xml index 724effb2ced..c879b848aa8 100644 --- a/xml/System.Linq/Enumerable.xml +++ b/xml/System.Linq/Enumerable.xml @@ -414,7 +414,52 @@ This method is comparable to the methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. - + + + The following example demonstrates how to use AggregateBy with a seed selector to compute multiple values per key. + + + class Employee + { + public string Name { get; set; } + public string Department { get; set; } + public decimal Salary { get; set; } + } + + public static void AggregateBySeedSelectorExample() + { + Employee[] employees = + { + new Employee { Name = "Ali", Department = "HR", Salary = 45000 }, + new Employee { Name = "Samer", Department = "Technology", Salary = 50000 }, + new Employee { Name = "Hamed", Department = "Sales", Salary = 75000 }, + new Employee { Name = "Lina", Department = "Technology", Salary = 65000 }, + new Employee { Name = "Omar", Department = "HR", Salary = 40000 } + }; + + var result = + employees.AggregateBy( + e => e.Department, + dept => (Total: 0m, Count: 0), + (acc, e) => (acc.Total + e.Salary, acc.Count + 1) + ); + + foreach (var item in result) + { + Console.WriteLine($"{item.Key}: Total={item.Value.Total}, Count={item.Value.Count}"); + } + } + + /* + This code produces the following output: + + HR: Total=85000, Count=2 + Technology: Total=115000, Count=2 + Sales: Total=75000, Count=1 + */ + + + @@ -491,6 +536,52 @@ This method is comparable to the methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. + + + The following example demonstrates how to use AggregateBy with a constant seed value to compute totals per key. + + + class Employee + { + public string Name { get; set; } + public string Department { get; set; } + public decimal Salary { get; set; } + } + + public static void AggregateBySeedExample() + { + Employee[] employees = + { + new Employee { Name = "Ali", Department = "HR", Salary = 45000 }, + new Employee { Name = "Samer", Department = "Technology", Salary = 50000 }, + new Employee { Name = "Hamed", Department = "Sales", Salary = 75000 }, + new Employee { Name = "Lina", Department = "Technology", Salary = 65000 }, + new Employee { Name = "Omar", Department = "HR", Salary = 40000 } + }; + + // Compute total salary per department using a constant seed + var totals = + employees.AggregateBy( + e => e.Department, + 0m, + (total, e) => total + e.Salary + ); + + foreach (var item in totals) + { + Console.WriteLine($"{item.Key}: {item.Value}"); + } + } + + /* + This code produces the following output: + + HR: 85000 + Technology: 115000 + Sales: 75000 + */ + + From baffd4308068abcace9a5a39c7a8429b23509569 Mon Sep 17 00:00:00 2001 From: Mahmoud Bakir Date: Thu, 9 Apr 2026 14:34:55 +0530 Subject: [PATCH 02/10] Add AggregateBy examples to documentation per PR feedback --- .../Enumerable/AggregateTSource/enumerable.cs | 80 ++++++++ xml/System.Linq/Enumerable.xml | 171 ++++++------------ 2 files changed, 132 insertions(+), 119 deletions(-) diff --git a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs index c55f5ec6902..43df184bba0 100644 --- a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs +++ b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs @@ -3204,5 +3204,85 @@ static void TakeLast() #endif } #endregion + + #region AggregateBy + static class AggregateBy + { + // + class Employee + { + public string Name { get; set; } + public string Department { get; set; } + public decimal Salary { get; set; } + } + + public static void AggregateBySeedSelectorExample() + { + Employee[] employees = + { + new Employee { Name = "Ali", Department = "HR", Salary = 45000 }, + new Employee { Name = "Samer", Department = "Technology", Salary = 50000 }, + new Employee { Name = "Hamed", Department = "Sales", Salary = 75000 }, + new Employee { Name = "Lina", Department = "Technology", Salary = 65000 }, + new Employee { Name = "Omar", Department = "HR", Salary = 40000 } + }; + + var result = + employees.AggregateBy( + e => e.Department, + dept => (Total: 0m, Count: 0), + (acc, e) => (acc.Total + e.Salary, acc.Count + 1) + ); + + foreach (var item in result) + { + Console.WriteLine($"{item.Key}: Total={item.Value.Total}, Count={item.Value.Count}"); + } + + /* + This code produces the following output: + + HR: Total=85000, Count=2 + Technology: Total=115000, Count=2 + Sales: Total=75000, Count=1 + */ + } + // + + // + public static void AggregateBySeedExample() + { + Employee[] employees = + { + new Employee { Name = "Ali", Department = "HR", Salary = 45000 }, + new Employee { Name = "Samer", Department = "Technology", Salary = 50000 }, + new Employee { Name = "Hamed", Department = "Sales", Salary = 75000 }, + new Employee { Name = "Lina", Department = "Technology", Salary = 65000 }, + new Employee { Name = "Omar", Department = "HR", Salary = 40000 } + }; + + var totals = + employees.AggregateBy( + e => e.Department, + 0m, + (total, e) => total + e.Salary + ); + + foreach (var item in totals) + { + Console.WriteLine($"{item.Key}: {item.Value}"); + } + + /* + This code produces the following output: + + HR: 85000 + Technology: 115000 + Sales: 75000 + */ + } + // + } + #endregion } } diff --git a/xml/System.Linq/Enumerable.xml b/xml/System.Linq/Enumerable.xml index c879b848aa8..8a62c2a6d9b 100644 --- a/xml/System.Linq/Enumerable.xml +++ b/xml/System.Linq/Enumerable.xml @@ -400,65 +400,32 @@ - - The type of the elements of . - The type of the key returned by . - The type of the accumulator value. - An to aggregate over. - A function to extract the key for each element. - A factory for the initial accumulator value. - An accumulator function to be invoked on each element. - An to compare keys with. - Applies an accumulator function over a sequence, grouping results by key. - An enumerable containing the aggregates corresponding to each key deriving from . - - This method is comparable to the methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. - - - - The following example demonstrates how to use AggregateBy with a seed selector to compute multiple values per key. - - - class Employee - { - public string Name { get; set; } - public string Department { get; set; } - public decimal Salary { get; set; } - } - - public static void AggregateBySeedSelectorExample() - { - Employee[] employees = - { - new Employee { Name = "Ali", Department = "HR", Salary = 45000 }, - new Employee { Name = "Samer", Department = "Technology", Salary = 50000 }, - new Employee { Name = "Hamed", Department = "Sales", Salary = 75000 }, - new Employee { Name = "Lina", Department = "Technology", Salary = 65000 }, - new Employee { Name = "Omar", Department = "HR", Salary = 40000 } - }; - - var result = - employees.AggregateBy( - e => e.Department, - dept => (Total: 0m, Count: 0), - (acc, e) => (acc.Total + e.Salary, acc.Count + 1) - ); - - foreach (var item in result) - { - Console.WriteLine($"{item.Key}: Total={item.Value.Total}, Count={item.Value.Count}"); - } - } - - /* - This code produces the following output: - - HR: Total=85000, Count=2 - Technology: Total=115000, Count=2 - Sales: Total=75000, Count=1 - */ - - + + The type of the elements of . + The type of the key returned by . + The type of the accumulator value. + An to aggregate over. + A function to extract the key for each element. + A factory for the initial accumulator value. + An accumulator function to be invoked on each element. + An to compare keys with. + Applies an accumulator function over a sequence, grouping results by key. + An enumerable containing the aggregates corresponding to each key deriving from . + + methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. + +## Examples + +The following example demonstrates how to use `AggregateBy` with a seed selector to compute multiple values per key. + +:::code language="csharp" source="~/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs" id="Snippet205"::: + + ]]> + @@ -523,66 +490,32 @@ - The type of the elements of . - The type of the key returned by . - The type of the accumulator value. - An to aggregate over. - A function to extract the key for each element. - The initial accumulator value. - An accumulator function to be invoked on each element. - An to compare keys with. - Applies an accumulator function over a sequence, grouping results by key. - An enumerable containing the aggregates corresponding to each key deriving from . - - This method is comparable to the methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. - - - - The following example demonstrates how to use AggregateBy with a constant seed value to compute totals per key. - - - class Employee - { - public string Name { get; set; } - public string Department { get; set; } - public decimal Salary { get; set; } - } - - public static void AggregateBySeedExample() - { - Employee[] employees = - { - new Employee { Name = "Ali", Department = "HR", Salary = 45000 }, - new Employee { Name = "Samer", Department = "Technology", Salary = 50000 }, - new Employee { Name = "Hamed", Department = "Sales", Salary = 75000 }, - new Employee { Name = "Lina", Department = "Technology", Salary = 65000 }, - new Employee { Name = "Omar", Department = "HR", Salary = 40000 } - }; - - // Compute total salary per department using a constant seed - var totals = - employees.AggregateBy( - e => e.Department, - 0m, - (total, e) => total + e.Salary - ); - - foreach (var item in totals) - { - Console.WriteLine($"{item.Key}: {item.Value}"); - } - } - - /* - This code produces the following output: - - HR: 85000 - Technology: 115000 - Sales: 75000 - */ - - - + The type of the elements of . + The type of the key returned by . + The type of the accumulator value. + An to aggregate over. + A function to extract the key for each element. + The initial accumulator value. + An accumulator function to be invoked on each element. + An to compare keys with. + Applies an accumulator function over a sequence, grouping results by key. + An enumerable containing the aggregates corresponding to each key deriving from . + + methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. + +## Examples + +The following example demonstrates how to use `AggregateBy` with a constant seed value to compute totals per key. + +:::code language="csharp" source="~/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs" id="Snippe"::: + + ]]> + + From 36e864214403df3ab12e01db3c2d12e00f96696a Mon Sep 17 00:00:00 2001 From: Mahmoud Bakir Date: Thu, 9 Apr 2026 16:05:36 +0530 Subject: [PATCH 03/10] Fixing typo in the id of Snippet --- xml/System.Linq/Enumerable.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/System.Linq/Enumerable.xml b/xml/System.Linq/Enumerable.xml index 8a62c2a6d9b..e13cbe799d0 100644 --- a/xml/System.Linq/Enumerable.xml +++ b/xml/System.Linq/Enumerable.xml @@ -511,7 +511,7 @@ This method is comparable to the method The following example demonstrates how to use `AggregateBy` with a constant seed value to compute totals per key. -:::code language="csharp" source="~/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs" id="Snippe"::: +:::code language="csharp" source="~/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs" id="Snippet206"::: ]]> From 4153e73ddf45b542ee70538d0044add8dc283813 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Thu, 9 Apr 2026 12:49:06 -0700 Subject: [PATCH 04/10] Update Enumerable.xml --- xml/System.Linq/Enumerable.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/System.Linq/Enumerable.xml b/xml/System.Linq/Enumerable.xml index e13cbe799d0..47267d5eaad 100644 --- a/xml/System.Linq/Enumerable.xml +++ b/xml/System.Linq/Enumerable.xml @@ -416,7 +416,7 @@ ## Remarks -This method is comparable to the methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. +This method is comparable to the methods where each grouping is aggregated into a single value as opposed to allocating a collection for each group. ## Examples From 6b5a5a29832284d0d75a5f328f3ef9e602d05633 Mon Sep 17 00:00:00 2001 From: Mahmoud Bakir Date: Fri, 10 Apr 2026 01:35:34 +0530 Subject: [PATCH 05/10] Update snippet project to target .NET 9 --- .../System.Linq/Enumerable/AggregateTSource/Enumerable.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/Enumerable.csproj b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/Enumerable.csproj index a269962b552..92e46ddaccf 100644 --- a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/Enumerable.csproj +++ b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/Enumerable.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 From fa940db2d71d8c9ab9e820ebca13114386971666 Mon Sep 17 00:00:00 2001 From: Bakir <133803989+mahmoudbakeer@users.noreply.github.com> Date: Sat, 11 Apr 2026 08:53:36 +0530 Subject: [PATCH 06/10] Update snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- .../Enumerable/AggregateTSource/enumerable.cs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs index 43df184bba0..ad4ee9989f0 100644 --- a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs +++ b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs @@ -3209,22 +3209,15 @@ static void TakeLast() static class AggregateBy { // - class Employee - { - public string Name { get; set; } - public string Department { get; set; } - public decimal Salary { get; set; } - } - public static void AggregateBySeedSelectorExample() { - Employee[] employees = + (string Name, string Department, decimal Salary)[] employees = { - new Employee { Name = "Ali", Department = "HR", Salary = 45000 }, - new Employee { Name = "Samer", Department = "Technology", Salary = 50000 }, - new Employee { Name = "Hamed", Department = "Sales", Salary = 75000 }, - new Employee { Name = "Lina", Department = "Technology", Salary = 65000 }, - new Employee { Name = "Omar", Department = "HR", Salary = 40000 } + ("Ali", "HR", 45000), + ("Samer", "Technology", 50000), + ("Hamed", "Sales", 75000), + ("Lina", "Technology", 65000), + ("Omar", "HR", 40000) }; var result = From 2c65f7b3c42dcd3687d0d56ff589ebf02bcd258a Mon Sep 17 00:00:00 2001 From: Bakir <133803989+mahmoudbakeer@users.noreply.github.com> Date: Sat, 11 Apr 2026 08:53:52 +0530 Subject: [PATCH 07/10] Update snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Enumerable/AggregateTSource/enumerable.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs index ad4ee9989f0..16625939d54 100644 --- a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs +++ b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs @@ -3245,13 +3245,13 @@ public static void AggregateBySeedSelectorExample() // public static void AggregateBySeedExample() { - Employee[] employees = + (string Name, string Department, decimal Salary)[] employees = { - new Employee { Name = "Ali", Department = "HR", Salary = 45000 }, - new Employee { Name = "Samer", Department = "Technology", Salary = 50000 }, - new Employee { Name = "Hamed", Department = "Sales", Salary = 75000 }, - new Employee { Name = "Lina", Department = "Technology", Salary = 65000 }, - new Employee { Name = "Omar", Department = "HR", Salary = 40000 } + ("Ali", "HR", 45000), + ("Samer", "Technology", 50000), + ("Hamed", "Sales", 75000), + ("Lina", "Technology", 65000), + ("Omar", "HR", 40000) }; var totals = From 93faec0fa01cf39bcf7e89f9db3e27d1ebd99e19 Mon Sep 17 00:00:00 2001 From: Mahmoud Bakir Date: Sat, 11 Apr 2026 10:53:01 +0530 Subject: [PATCH 08/10] Update XML xref per maintainer feedback --- xml/System.Linq/Enumerable.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xml/System.Linq/Enumerable.xml b/xml/System.Linq/Enumerable.xml index 47267d5eaad..1d5fc3e13a3 100644 --- a/xml/System.Linq/Enumerable.xml +++ b/xml/System.Linq/Enumerable.xml @@ -505,8 +505,7 @@ The following example demonstrates how to use `AggregateBy` with a seed selector ## Remarks -This method is comparable to the methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. - +This method is comparable to the methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. ## Examples The following example demonstrates how to use `AggregateBy` with a constant seed value to compute totals per key. From 07dcc5456a42f8d98cd660d0290ef9a7645c3784 Mon Sep 17 00:00:00 2001 From: Mahmoud Bakir Date: Sat, 11 Apr 2026 11:10:41 +0530 Subject: [PATCH 09/10] Restore blank line before Examples heading --- xml/System.Linq/Enumerable.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/xml/System.Linq/Enumerable.xml b/xml/System.Linq/Enumerable.xml index 1d5fc3e13a3..a5920f035ae 100644 --- a/xml/System.Linq/Enumerable.xml +++ b/xml/System.Linq/Enumerable.xml @@ -506,6 +506,7 @@ The following example demonstrates how to use `AggregateBy` with a seed selector ## Remarks This method is comparable to the methods where each grouping is being aggregated into a single value as opposed to allocating a collection for each group. + ## Examples The following example demonstrates how to use `AggregateBy` with a constant seed value to compute totals per key. From c9c9b6d3bbdfb98ab15fec0cedad90e90569b6fc Mon Sep 17 00:00:00 2001 From: Mahmoud Bakir Date: Fri, 17 Apr 2026 16:11:02 +0530 Subject: [PATCH 10/10] Add CountBy documentation example --- .../Enumerable/AggregateTSource/enumerable.cs | 39 +++++++++++++++++++ xml/System.Linq/Enumerable.xml | 12 +++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs index b1acf2a1430..1b141106229 100644 --- a/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs +++ b/snippets/csharp/System.Linq/Enumerable/AggregateTSource/enumerable.cs @@ -3357,5 +3357,44 @@ Sara Jones (Sara.jones@example.com) // } #endregion + + #region CountBy + static class CountBy + { + + public static void CountByDepartmentExample() + { + // + (string Name, int Age, string Department)[] employees = + { + ("Saly", 23, "IT"), + ("David", 25, "Sales"), + ("Mahmoud", 22, "IT"), + ("Qamar", 22, "HR"), + ("Sara", 25, "IT"), + ("John", 26, "HR"), + ("Jaffar", 32, "Sales") + }; + + // Count the number of employees per department + var countPerDepartment = employees.CountBy(employee => employee.Department); + + foreach (var item in countPerDepartment) + { + Console.WriteLine($"Department: {item.Key} - Employees Count: {item.Value}"); + } + + /* + This code produces the following output: + + Department: IT - Employees Count: 3 + Department: Sales - Employees Count: 2 + Department: HR - Employees Count: 2 + */ + // + } + + } + #endregion } } diff --git a/xml/System.Linq/Enumerable.xml b/xml/System.Linq/Enumerable.xml index 95791bba536..6062de43daa 100644 --- a/xml/System.Linq/Enumerable.xml +++ b/xml/System.Linq/Enumerable.xml @@ -3004,7 +3004,17 @@ Each chunk except the last one will be of size `size`. The last chunk will conta An to compare keys with. Returns the count of elements in the source sequence grouped by key. An enumerable containing the frequencies of each key occurrence in . - To be added. + + +