Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type safety and improve type inference #1374

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 0 additions & 64 deletions UnitsNet.Tests/UnitMathTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,6 @@ public void AbsoluteValueOfNullReferenceThrowsException()
Assert.Throws<NullReferenceException>(() => quantity.Abs());
}

[Fact]
public void AverageOfDifferentUnitsThrowsException()
{
var units = new IQuantity[] {Length.FromMeters(1), Volume.FromLiters(50)};

Assert.Throws<ArgumentException>(() => units.Average(LengthUnit.Centimeter));
}

[Fact]
public void AverageOfEmptySourceThrowsException()
{
Expand All @@ -61,14 +53,6 @@ public void AverageOfEmptySourceThrowsException()
Assert.Throws<InvalidOperationException>(() => units.Average(LengthUnit.Centimeter));
}

[Fact]
public void AverageOfLengthsWithNullValueThrowsException()
{
var units = new IQuantity[] {Length.FromMeters(1), null!};

Assert.Throws<NullReferenceException>(() => units.Average(LengthUnit.Centimeter));
}

[Fact]
public void AverageOfLengthsCalculatesCorrectly()
{
Expand Down Expand Up @@ -119,22 +103,6 @@ public void MaxOfTwoLengthsReturnsTheLargestValue()
Assert.Equal(LengthUnit.Meter, max.Unit);
}

[Fact]
public void MaxOfDifferentUnitsThrowsException()
{
var units = new IQuantity[] {Length.FromMeters(1), Volume.FromLiters(50)};

Assert.Throws<ArgumentException>(() => units.Max(LengthUnit.Centimeter));
}

[Fact]
public void MaxOfLengthsWithNullValueThrowsException()
{
var units = new IQuantity[] {Length.FromMeters(1), null!};

Assert.Throws<NullReferenceException>(() => units.Max(LengthUnit.Centimeter));
}

[Fact]
public void MaxOfEmptySourceThrowsException()
{
Expand Down Expand Up @@ -193,22 +161,6 @@ public void MinOfTwoLengthsReturnsTheSmallestValue()
Assert.Equal(LengthUnit.Centimeter, min.Unit);
}

[Fact]
public void MinOfDifferentUnitsThrowsException()
{
var units = new IQuantity[] {Length.FromMeters(1), Volume.FromLiters(50)};

Assert.Throws<ArgumentException>(() => units.Min(LengthUnit.Centimeter));
}

[Fact]
public void MinOfLengthsWithNullValueThrowsException()
{
var units = new IQuantity[] {Length.FromMeters(1), null!};

Assert.Throws<NullReferenceException>(() => units.Min(LengthUnit.Centimeter));
}

[Fact]
public void MinOfEmptySourceThrowsException()
{
Expand Down Expand Up @@ -255,22 +207,6 @@ public void MinOfLengthsWithSelectorCalculatesCorrectly()
Assert.Equal(LengthUnit.Centimeter, min.Unit);
}

[Fact]
public void SumOfDifferentUnitsThrowsException()
{
var units = new IQuantity[] {Length.FromMeters(1), Volume.FromLiters(50)};

Assert.Throws<ArgumentException>(() => units.Sum(LengthUnit.Centimeter));
}

[Fact]
public void SumOfLengthsWithNullValueThrowsException()
{
var units = new IQuantity[] {Length.FromMeters(1), null!};

Assert.Throws<NullReferenceException>(() => units.Sum(LengthUnit.Centimeter));
}

[Fact]
public void SumOfEmptySourceReturnsZero()
{
Expand Down
52 changes: 32 additions & 20 deletions UnitsNet/UnitMath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ public static TQuantity Abs<TQuantity>(this TQuantity value) where TQuantity : I
/// <exception cref="ArgumentException">
/// <paramref name="source">source</paramref> contains quantity types different from <paramref name="unitType" />.
/// </exception>
public static TQuantity Sum<TQuantity>(this IEnumerable<TQuantity> source, Enum unitType)
where TQuantity : IQuantity
public static TQuantity Sum<TQuantity, TUnitType>(this IEnumerable<TQuantity> source, TUnitType unitType)
where TUnitType : Enum
where TQuantity : IQuantity<TUnitType>
{
return (TQuantity) Quantity.From(source.Sum(x => x.As(unitType)), unitType);
}
Expand All @@ -44,16 +45,18 @@ public static TQuantity Sum<TQuantity>(this IEnumerable<TQuantity> source, Enum
/// <param name="selector">A transform function to apply to each element.</param>
/// <param name="unitType">The desired unit type for the resulting quantity</param>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <typeparam name="TQuantity">The type of quantity that is produced by this operation</typeparam>
/// <typeparam name="TQuantity">The type of quantity that is produced by this operation.</typeparam>
/// <typeparam name="TUnitType">The type of unit enum.</typeparam>
/// <returns>The sum of the projected values, represented in the specified unit type.</returns>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="source">source</paramref> or <paramref name="selector">selector</paramref> is null.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="source">source</paramref> contains quantity types different from <paramref name="unitType" />.
/// </exception>
public static TQuantity Sum<TSource, TQuantity>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, Enum unitType)
where TQuantity : IQuantity
public static TQuantity Sum<TSource, TQuantity, TUnitType>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnitType unitType)
where TUnitType : Enum
where TQuantity : IQuantity<TUnitType>
{
return source.Select(selector).Sum(unitType);
}
Expand All @@ -79,8 +82,9 @@ public static TQuantity Min<TQuantity>(TQuantity val1, TQuantity val2) where TQu
/// <exception cref="ArgumentException">
/// <paramref name="source">source</paramref> contains quantity types different from <paramref name="unitType" />.
/// </exception>
public static TQuantity Min<TQuantity>(this IEnumerable<TQuantity> source, Enum unitType)
where TQuantity : IQuantity
public static TQuantity Min<TQuantity, TUnitType>(this IEnumerable<TQuantity> source, TUnitType unitType)
where TUnitType : Enum
where TQuantity : IQuantity<TUnitType>
{
return (TQuantity) Quantity.From(source.Min(x => x.As(unitType)), unitType);
}
Expand All @@ -93,7 +97,8 @@ public static TQuantity Min<TQuantity>(this IEnumerable<TQuantity> source, Enum
/// <param name="selector">A transform function to apply to each element.</param>
/// <param name="unitType">The desired unit type for the resulting quantity</param>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <typeparam name="TQuantity">The type of quantity that is produced by this operation</typeparam>
/// <typeparam name="TQuantity">The type of quantity that is produced by this operation.</typeparam>
/// <typeparam name="TUnitType">The type of unit enum.</typeparam>
/// <returns>The min of the projected values, represented in the specified unit type.</returns>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="source">source</paramref> or <paramref name="selector">selector</paramref> is null.
Expand All @@ -102,8 +107,9 @@ public static TQuantity Min<TQuantity>(this IEnumerable<TQuantity> source, Enum
/// <exception cref="ArgumentException">
/// <paramref name="source">source</paramref> contains quantity types different from <paramref name="unitType" />.
/// </exception>
public static TQuantity Min<TSource, TQuantity>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, Enum unitType)
where TQuantity : IQuantity
public static TQuantity Min<TSource, TQuantity, TUnitType>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnitType unitType)
where TUnitType : Enum
where TQuantity : IQuantity<TUnitType>
{
return source.Select(selector).Min(unitType);
}
Expand All @@ -129,8 +135,9 @@ public static TQuantity Max<TQuantity>(TQuantity val1, TQuantity val2) where TQu
/// <exception cref="ArgumentException">
/// <paramref name="source">source</paramref> contains quantity types different from <paramref name="unitType" />.
/// </exception>
public static TQuantity Max<TQuantity>(this IEnumerable<TQuantity> source, Enum unitType)
where TQuantity : IQuantity
public static TQuantity Max<TQuantity, TUnitType>(this IEnumerable<TQuantity> source, TUnitType unitType)
where TUnitType : Enum
where TQuantity : IQuantity<TUnitType>
{
return (TQuantity) Quantity.From(source.Max(x => x.As(unitType)), unitType);
}
Expand All @@ -143,7 +150,8 @@ public static TQuantity Max<TQuantity>(this IEnumerable<TQuantity> source, Enum
/// <param name="selector">A transform function to apply to each element.</param>
/// <param name="unitType">The desired unit type for the resulting quantity</param>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <typeparam name="TQuantity">The type of quantity that is produced by this operation</typeparam>
/// <typeparam name="TQuantity">The type of quantity that is produced by this operation.</typeparam>
/// <typeparam name="TUnitType">The type of unit enum.</typeparam>
/// <returns>The max of the projected values, represented in the specified unit type.</returns>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="source">source</paramref> or <paramref name="selector">selector</paramref> is null.
Expand All @@ -152,8 +160,9 @@ public static TQuantity Max<TQuantity>(this IEnumerable<TQuantity> source, Enum
/// <exception cref="ArgumentException">
/// <paramref name="source">source</paramref> contains quantity types different from <paramref name="unitType" />.
/// </exception>
public static TQuantity Max<TSource, TQuantity>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, Enum unitType)
where TQuantity : IQuantity
public static TQuantity Max<TSource, TQuantity, TUnitType>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnitType unitType)
where TUnitType : Enum
where TQuantity : IQuantity<TUnitType>
{
return source.Select(selector).Max(unitType);
}
Expand All @@ -169,8 +178,9 @@ public static TQuantity Max<TSource, TQuantity>(this IEnumerable<TSource> source
/// <exception cref="ArgumentException">
/// <paramref name="source">source</paramref> contains quantity types different from <paramref name="unitType" />.
/// </exception>
public static TQuantity Average<TQuantity>(this IEnumerable<TQuantity> source, Enum unitType)
where TQuantity : IQuantity
public static TQuantity Average<TQuantity, TUnitType>(this IEnumerable<TQuantity> source, TUnitType unitType)
where TUnitType : Enum
where TQuantity : IQuantity<TUnitType>
{
return (TQuantity) Quantity.From(source.Average(x => x.As(unitType)), unitType);
}
Expand All @@ -183,7 +193,8 @@ public static TQuantity Average<TQuantity>(this IEnumerable<TQuantity> source, E
/// <param name="selector">A transform function to apply to each element.</param>
/// <param name="unitType">The desired unit type for the resulting quantity</param>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <typeparam name="TQuantity">The type of quantity that is produced by this operation</typeparam>
/// <typeparam name="TQuantity">The type of quantity that is produced by this operation.</typeparam>
/// <typeparam name="TUnitType">The type of unit enum.</typeparam>
/// <returns>The average of the projected values, represented in the specified unit type.</returns>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="source">source</paramref> or <paramref name="selector">selector</paramref> is null.
Expand All @@ -192,8 +203,9 @@ public static TQuantity Average<TQuantity>(this IEnumerable<TQuantity> source, E
/// <exception cref="ArgumentException">
/// <paramref name="source">source</paramref> contains quantity types different from <paramref name="unitType" />.
/// </exception>
public static TQuantity Average<TSource, TQuantity>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, Enum unitType)
where TQuantity : IQuantity
public static TQuantity Average<TSource, TQuantity, TUnitType>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnitType unitType)
where TUnitType : Enum
where TQuantity : IQuantity<TUnitType>
{
return source.Select(selector).Average(unitType);
}
Expand Down