From b1c644dc4789676256c034041c7d9487228d3889 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Thu, 14 Nov 2024 16:01:11 +0000 Subject: [PATCH] refactor!: replace Product and RangeTo on int types with generic math --- CHANGELOG.md | 7 ++ X10D.Tests/src/Linq/ByteTests.cs | 47 +-------- X10D.Tests/src/Linq/Int16Tests.cs | 34 +----- X10D.Tests/src/Linq/Int32Tests.cs | 16 +-- X10D.Tests/src/Linq/Int64Tests.cs | 2 +- X10D/src/Linq/ByteExtensions.cs | 161 ----------------------------- X10D/src/Linq/DecimalExtensions.cs | 42 -------- X10D/src/Linq/DoubleExtensions.cs | 42 -------- X10D/src/Linq/Int16Extensions.cs | 117 --------------------- X10D/src/Linq/Int32Extensions.cs | 121 ---------------------- X10D/src/Linq/Int64Extensions.cs | 101 ------------------ X10D/src/Linq/NumberExtensions.cs | 72 +++++++++++++ X10D/src/Linq/SingleExtensions.cs | 42 -------- 13 files changed, 83 insertions(+), 721 deletions(-) delete mode 100644 X10D/src/Linq/ByteExtensions.cs delete mode 100644 X10D/src/Linq/DecimalExtensions.cs delete mode 100644 X10D/src/Linq/DoubleExtensions.cs delete mode 100644 X10D/src/Linq/Int16Extensions.cs delete mode 100644 X10D/src/Linq/Int32Extensions.cs delete mode 100644 X10D/src/Linq/Int64Extensions.cs create mode 100644 X10D/src/Linq/NumberExtensions.cs delete mode 100644 X10D/src/Linq/SingleExtensions.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 521a00edd..08abffd1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 4.0.1 - [Unreleased] +### Changed + +- X10D: Removed `byte.Product`, `short.Product`, `ushort.Product`, `int.Product`, `uint.Product`, `long.Product`, + and `ulong.Product`, in favour of `INumber.Product`. +- X10D: Removed `byte.RangeTo`, `short.RangeTo`, `ushort.RangeTo`, `int.RangeTo`, `uint.RangeTo`, `long.RangeTo`, +and `ulong.RangeTo`, in favour of `INumber.RangeTo`. + ### Removed - X10D: Removed `Span.Split` for .NET 9.0 target due to conflicts with diff --git a/X10D.Tests/src/Linq/ByteTests.cs b/X10D.Tests/src/Linq/ByteTests.cs index a3b79e29d..bbd69c066 100644 --- a/X10D.Tests/src/Linq/ByteTests.cs +++ b/X10D.Tests/src/Linq/ByteTests.cs @@ -43,7 +43,7 @@ public void Product_ShouldThrowArgumentNullException_GivenNullSource() } [Test] - public void RangeTo_Byte_ShouldYieldCorrectValues() + public void RangeTo_ShouldYieldCorrectValues() { const byte start = 1; const byte end = 10; @@ -56,49 +56,4 @@ public void RangeTo_Byte_ShouldYieldCorrectValues() Assert.That(current, Is.EqualTo(end)); } - - [Test] - public void RangeTo_Int16_ShouldYieldCorrectValues() - { - const byte start = 1; - const short end = 10; - - short current = 1; - foreach (short value in start.RangeTo(end)) - { - Assert.That(value, Is.EqualTo(current++)); - } - - Assert.That(current, Is.EqualTo(end)); - } - - [Test] - public void RangeTo_Int32_ShouldYieldCorrectValues() - { - const byte start = 1; - const int end = 10; - - int current = 1; - foreach (int value in start.RangeTo(end)) - { - Assert.That(value, Is.EqualTo(current++)); - } - - Assert.That(current, Is.EqualTo(end)); - } - - [Test] - public void RangeTo_Int64_ShouldYieldCorrectValues() - { - const byte start = 1; - const long end = 10; - - long current = 1; - foreach (long value in start.RangeTo(end)) - { - Assert.That(value, Is.EqualTo(current++)); - } - - Assert.That(current, Is.EqualTo(end)); - } } diff --git a/X10D.Tests/src/Linq/Int16Tests.cs b/X10D.Tests/src/Linq/Int16Tests.cs index 1401d9e30..1c8c3c97c 100644 --- a/X10D.Tests/src/Linq/Int16Tests.cs +++ b/X10D.Tests/src/Linq/Int16Tests.cs @@ -46,7 +46,7 @@ public void Product_ShouldThrowArgumentNullException_GivenNullSource() } [Test] - public void RangeTo_Int16_ShouldYieldCorrectValues() + public void RangeTo_ShouldYieldCorrectValues() { const short start = 1; const short end = 10; @@ -60,36 +60,4 @@ public void RangeTo_Int16_ShouldYieldCorrectValues() Assert.That(current, Is.EqualTo(end)); } - - [Test] - public void RangeTo_Int32_ShouldYieldCorrectValues() - { - const short start = 1; - const int end = 10; - - var current = 1; - - foreach (int value in start.RangeTo(end)) - { - Assert.That(value, Is.EqualTo(current++)); - } - - Assert.That(current, Is.EqualTo(end)); - } - - [Test] - public void RangeTo_Int64_ShouldYieldCorrectValues() - { - const short start = 1; - const long end = 10; - - long current = 1; - - foreach (long value in start.RangeTo(end)) - { - Assert.That(value, Is.EqualTo(current++)); - } - - Assert.That(current, Is.EqualTo(end)); - } } diff --git a/X10D.Tests/src/Linq/Int32Tests.cs b/X10D.Tests/src/Linq/Int32Tests.cs index 783cbbac0..9d5f0b3b7 100644 --- a/X10D.Tests/src/Linq/Int32Tests.cs +++ b/X10D.Tests/src/Linq/Int32Tests.cs @@ -50,7 +50,7 @@ public void Product_ShouldThrowArgumentNullException_GivenNullSource() } [Test] - public void RangeTo_Int32_ShouldYieldCorrectValues() + public void RangeTo_ShouldYieldCorrectValues() { const int start = 1; const int end = 10; @@ -64,18 +64,4 @@ public void RangeTo_Int32_ShouldYieldCorrectValues() Assert.That(current, Is.EqualTo(end)); } - [Test] - public void RangeTo_Int64_ShouldYieldCorrectValues() - { - const int start = 1; - const long end = 10; - - long current = 1; - foreach (long value in start.RangeTo(end)) - { - Assert.That(value, Is.EqualTo(current++)); - } - - Assert.That(current, Is.EqualTo(end)); - } } diff --git a/X10D.Tests/src/Linq/Int64Tests.cs b/X10D.Tests/src/Linq/Int64Tests.cs index c55f74df2..9cd525bc8 100644 --- a/X10D.Tests/src/Linq/Int64Tests.cs +++ b/X10D.Tests/src/Linq/Int64Tests.cs @@ -51,7 +51,7 @@ public void Product_ShouldThrowArgumentNullException_GivenNullSource() } [Test] - public void RangeTo_Int64_ShouldYieldCorrectValues() + public void RangeTo_ShouldYieldCorrectValues() { const long start = 1; const long end = 10; diff --git a/X10D/src/Linq/ByteExtensions.cs b/X10D/src/Linq/ByteExtensions.cs deleted file mode 100644 index 992507c87..000000000 --- a/X10D/src/Linq/ByteExtensions.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System.Diagnostics.Contracts; - -namespace X10D.Linq; - -/// -/// LINQ-inspired extension methods for of . -/// -public static class ByteExtensions -{ - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - /// is . - public static byte Product(this IEnumerable source) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Aggregate((byte)1, (current, value) => (byte)(current * value)); - } - - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - /// is . - [CLSCompliant(false)] - public static sbyte Product(this IEnumerable source) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Aggregate((sbyte)1, (current, value) => (sbyte)(current * value)); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function - /// on each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - /// is . - public static byte Product(this IEnumerable source, Func selector) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Select(selector).Product(); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function - /// on each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - /// is . - [CLSCompliant(false)] - public static sbyte Product(this IEnumerable source, Func selector) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Select(selector).Product(); - } - - /// - /// Returns an enumerable sequence of 8-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 8-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this byte value, byte end) - { - byte start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (byte current = start; current < end; current++) - { - yield return current; - } - } - - /// - /// Returns an enumerable sequence of 16-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 16-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this byte value, short end) - { - short start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (short current = start; current < end; current++) - { - yield return current; - } - } - - /// - /// Returns an enumerable sequence of 32-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 32-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this byte value, int end) - { - int start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (int current = start; current < end; current++) - { - yield return current; - } - } - - /// - /// Returns an enumerable sequence of 64-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 64-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this byte value, long end) - { - long start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (long current = start; current < end; current++) - { - yield return current; - } - } -} diff --git a/X10D/src/Linq/DecimalExtensions.cs b/X10D/src/Linq/DecimalExtensions.cs deleted file mode 100644 index 16ca5e9bd..000000000 --- a/X10D/src/Linq/DecimalExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -namespace X10D.Linq; - -/// -/// LINQ-inspired extension methods for of . -/// -public static class DecimalExtensions -{ - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - /// is . - public static decimal Product(this IEnumerable source) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Aggregate(1m, (current, value) => (current * value)); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function - /// on each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - /// is . - public static decimal Product(this IEnumerable source, Func selector) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Select(selector).Product(); - } -} diff --git a/X10D/src/Linq/DoubleExtensions.cs b/X10D/src/Linq/DoubleExtensions.cs deleted file mode 100644 index 464a0d6de..000000000 --- a/X10D/src/Linq/DoubleExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -namespace X10D.Linq; - -/// -/// LINQ-inspired extension methods for of . -/// -public static class DoubleExtensions -{ - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - /// is . - public static double Product(this IEnumerable source) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Aggregate(1.0, (current, value) => (current * value)); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function - /// on each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - /// is . - public static double Product(this IEnumerable source, Func selector) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Select(selector).Product(); - } -} diff --git a/X10D/src/Linq/Int16Extensions.cs b/X10D/src/Linq/Int16Extensions.cs deleted file mode 100644 index 46e082e1b..000000000 --- a/X10D/src/Linq/Int16Extensions.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System.Diagnostics.Contracts; - -namespace X10D.Linq; - -/// -/// LINQ-inspired extension methods for of . -/// -public static class Int16Extensions -{ - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - public static short Product(this IEnumerable source) - { - return source.Aggregate((short)1, (current, value) => (short)(current * value)); - } - - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - [CLSCompliant(false)] - public static ushort Product(this IEnumerable source) - { - return source.Aggregate((ushort)1, (current, value) => (ushort)(current * value)); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function - /// on each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - public static short Product(this IEnumerable source, Func selector) - { - return source.Select(selector).Product(); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function - /// on each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - [CLSCompliant(false)] - public static ushort Product(this IEnumerable source, Func selector) - { - return source.Select(selector).Product(); - } - - /// - /// Returns an enumerable sequence of 16-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 16-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this short value, short end) - { - short start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (short current = start; current < end; current++) - { - yield return current; - } - } - - /// - /// Returns an enumerable sequence of 32-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 32-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this short value, int end) - { - int start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (int current = start; current < end; current++) - { - yield return current; - } - } - - /// - /// Returns an enumerable sequence of 64-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 64-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this short value, long end) - { - long start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (long current = start; current < end; current++) - { - yield return current; - } - } -} diff --git a/X10D/src/Linq/Int32Extensions.cs b/X10D/src/Linq/Int32Extensions.cs deleted file mode 100644 index 3aca60b81..000000000 --- a/X10D/src/Linq/Int32Extensions.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System.Diagnostics.Contracts; - -namespace X10D.Linq; - -/// -/// LINQ-inspired extension methods for of . -/// -public static class Int32Extensions -{ - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - /// is . - public static int Product(this IEnumerable source) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Aggregate(1, (current, value) => current * value); - } - - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - /// is . - [CLSCompliant(false)] - public static uint Product(this IEnumerable source) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Aggregate(1u, (current, value) => current * value); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function on - /// each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - /// is . - public static int Product(this IEnumerable source, Func selector) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Select(selector).Product(); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function on - /// each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - /// is . - [CLSCompliant(false)] - public static uint Product(this IEnumerable source, Func selector) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Select(selector).Product(); - } - - /// - /// Returns an enumerable sequence of 32-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 32-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this int value, int end) - { - int start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (int current = start; current < end; current++) - { - yield return current; - } - } - - /// - /// Returns an enumerable sequence of 64-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 64-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this int value, long end) - { - long start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (long current = start; current < end; current++) - { - yield return current; - } - } -} diff --git a/X10D/src/Linq/Int64Extensions.cs b/X10D/src/Linq/Int64Extensions.cs deleted file mode 100644 index 53dcf8f33..000000000 --- a/X10D/src/Linq/Int64Extensions.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Diagnostics.Contracts; - -namespace X10D.Linq; - -/// -/// LINQ-inspired extension methods for of . -/// -public static class Int64Extensions -{ - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - /// is . - public static long Product(this IEnumerable source) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Aggregate(1L, (current, value) => current * value); - } - - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - /// is . - [CLSCompliant(false)] - public static ulong Product(this IEnumerable source) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Aggregate(1UL, (current, value) => current * value); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function on - /// each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - /// is . - public static long Product(this IEnumerable source, Func selector) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Select(selector).Product(); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function - /// on each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - /// is . - [CLSCompliant(false)] - public static ulong Product(this IEnumerable source, Func selector) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Select(selector).Product(); - } - - /// - /// Returns an enumerable sequence of 64-bit integers ranging from the current value to a specified value. - /// - /// The starting value of the sequence. - /// The ending value of the sequence. - /// - /// An enumerable collection of 64-bit integers, ranging from to . - /// - [Pure] - public static IEnumerable RangeTo(this long value, long end) - { - long start = System.Math.Min(value, end); - end = System.Math.Max(value, end); - - for (long current = start; current < end; current++) - { - yield return current; - } - } -} diff --git a/X10D/src/Linq/NumberExtensions.cs b/X10D/src/Linq/NumberExtensions.cs new file mode 100644 index 000000000..a3d0668a8 --- /dev/null +++ b/X10D/src/Linq/NumberExtensions.cs @@ -0,0 +1,72 @@ +using System.Diagnostics.Contracts; +using System.Numerics; + +namespace X10D.Linq; + +/// +/// LINQ-inspired extension methods for of . +/// +public static class NumberExtensions +{ + /// + /// Computes the product of a sequence of values. + /// + /// A sequence of values that are used to calculate the product. + /// The type of the number for which to compute the product. + /// The product the values in the sequence. + /// is . + public static TNumber Product(this IEnumerable source) + where TNumber : INumber + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + return source.Aggregate(TNumber.MultiplicativeIdentity, (current, value) => current * value); + } + + /// + /// Computes the product of a sequence of values that are obtained by invoking a transform + /// function on each element of the input sequence. + /// + /// A sequence of values that are used to calculate a product. + /// A transform function to apply to each element. + /// The type of the elements of . + /// The type of the number for which to compute the product. + /// The product of the projected values. + /// is . + public static TNumber Product(this IEnumerable source, Func selector) + where TNumber : INumber + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + return source.Select(selector).Product(); + } + + /// + /// Returns an enumerable sequence of numbers ranging from the current value to a specified value. + /// + /// The starting value of the sequence. + /// The ending value of the sequence. + /// The type of the number for which to compute the product. + /// + /// An enumerable collection of , ranging from to + /// . + /// + [Pure] + public static IEnumerable RangeTo(this TNumber value, TNumber end) + where TNumber : INumber + { + TNumber start = TNumber.Min(value, end); + end = TNumber.Max(value, end); + + for (TNumber current = start; current < end; current++) + { + yield return current; + } + } +} diff --git a/X10D/src/Linq/SingleExtensions.cs b/X10D/src/Linq/SingleExtensions.cs deleted file mode 100644 index 2e873aff3..000000000 --- a/X10D/src/Linq/SingleExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -namespace X10D.Linq; - -/// -/// LINQ-inspired extension methods for of . -/// -public static class SingleExtensions -{ - /// - /// Computes the product of a sequence of values. - /// - /// A sequence of values that are used to calculate the product. - /// The product the values in the sequence. - /// is . - public static float Product(this IEnumerable source) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Aggregate(1f, (current, value) => (current * value)); - } - - /// - /// Computes the product of a sequence of values that are obtained by invoking a transform function - /// on each element of the input sequence. - /// - /// A sequence of values that are used to calculate a product. - /// A transform function to apply to each element. - /// The type of the elements of . - /// The product of the projected values. - /// is . - public static float Product(this IEnumerable source, Func selector) - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Select(selector).Product(); - } -}