Skip to content

Commit

Permalink
Expand numeric extension methods to nullable value types
Browse files Browse the repository at this point in the history
  • Loading branch information
skrysmanski committed Mar 18, 2024
1 parent 645c5e4 commit ed933b4
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 10 deletions.
48 changes: 42 additions & 6 deletions src/AppMotor.Core/Extensions/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,24 @@ public static class TypeExtensions
/// and <c>sbyte</c> as well as <see cref="BigInteger"/>. However, <see cref="Complex"/>
/// is excluded.
/// </summary>
/// <param name="type">The type to check</param>
/// <param name="includeNullables">Whether this method should return <c>true</c> for nullable
/// number types as well. If <c>true</c>, this method will return <c>true</c> for <c>int?</c>.
/// If <c>false</c>, it will return <c>false</c> in this case.</param>
/// <seealso cref="IsNumericIntegerType"/>
/// <seealso cref="IsNumericFloatType"/>
[MustUseReturnValue]
public static bool IsNumericType(this Type type)
public static bool IsNumericType(this Type type, bool includeNullables)
{
Validate.ArgumentWithName(nameof(type)).IsNotNull(type);
// Check if the type is a nullable value type and use the underlying type for the check.
if (includeNullables && type.IsValueType)
{
var underlyingType = Nullable.GetUnderlyingType(type);
if (underlyingType is not null)
{
return underlyingType.IsNumericType(includeNullables: false);
}
}

if (type.IsPrimitive)
{
Expand Down Expand Up @@ -77,12 +89,24 @@ public static bool IsNumericType(this Type type)
/// Returns whether this type is an integer type. This list includes <c>byte</c>, <c>sbyte</c>, <see cref="BigInteger"/>,
/// <c>Int128</c>, and <c>UInt128</c>.
/// </summary>
/// <param name="type">The type to check</param>
/// <param name="includeNullables">Whether this method should return <c>true</c> for nullable
/// number types as well. If <c>true</c>, this method will return <c>true</c> for <c>int?</c>.
/// If <c>false</c>, it will return <c>false</c> in this case.</param>
/// <seealso cref="IsNumericType"/>
/// <seealso cref="IsNumericFloatType"/>
[MustUseReturnValue]
public static bool IsNumericIntegerType(this Type type)
public static bool IsNumericIntegerType(this Type type, bool includeNullables)
{
Validate.ArgumentWithName(nameof(type)).IsNotNull(type);
// Check if the type is a nullable value type and use the underlying type for the check.
if (includeNullables && type.IsValueType)
{
var underlyingType = Nullable.GetUnderlyingType(type);
if (underlyingType is not null)
{
return underlyingType.IsNumericType(includeNullables: false);
}
}

if (type.IsPrimitive)
{
Expand Down Expand Up @@ -125,12 +149,24 @@ public static bool IsNumericIntegerType(this Type type)
/// Returns whether this type is a floating point type. This list includes <c>float</c>,
/// <c>double</c>, <c>decimal</c>, and <c>Half</c>.
/// </summary>
/// <param name="type">The type to check</param>
/// <param name="includeNullables">Whether this method should return <c>true</c> for nullable
/// number types as well. If <c>true</c>, this method will return <c>true</c> for <c>int?</c>.
/// If <c>false</c>, it will return <c>false</c> in this case.</param>
/// <seealso cref="IsNumericIntegerType"/>
/// <seealso cref="IsNumericType"/>
[MustUseReturnValue]
public static bool IsNumericFloatType(this Type type)
public static bool IsNumericFloatType(this Type type, bool includeNullables)
{
Validate.ArgumentWithName(nameof(type)).IsNotNull(type);
// Check if the type is a nullable value type and use the underlying type for the check.
if (includeNullables && type.IsValueType)
{
var underlyingType = Nullable.GetUnderlyingType(type);
if (underlyingType is not null)
{
return underlyingType.IsNumericType(includeNullables: false);
}
}

if (type.IsPrimitive)
{
Expand Down
2 changes: 1 addition & 1 deletion src/AppMotor.Core/Logging/LoggableValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public static bool IsSimpleLoggableType(Type typeToCheck)
typeToCheck = underlyingType;
}

if (typeToCheck.IsNumericType())
if (typeToCheck.IsNumericType(includeNullables: true))
{
return true;
}
Expand Down
27 changes: 24 additions & 3 deletions tests/AppMotor.Core.Tests/Tests/Extensions/TypeExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,14 @@ public sealed class TypeExtensionsTests
[InlineData(typeof(decimal), true)]
public void Test_IsNumericType(Type type, bool expectedResult)
{
type.IsNumericType().ShouldBe(expectedResult);
type.IsNumericType(includeNullables: false).ShouldBe(expectedResult);

if (expectedResult)
{
var nullableType = typeof(Nullable<>).MakeGenericType(type);
nullableType.IsNumericType(includeNullables: false).ShouldBe(false);
nullableType.IsNumericType(includeNullables: true).ShouldBe(true);
}
}

[Theory]
Expand All @@ -63,7 +70,14 @@ public void Test_IsNumericType(Type type, bool expectedResult)
[InlineData(typeof(decimal), false)]
public void Test_IsNumericIntegerType(Type type, bool expectedResult)
{
type.IsNumericIntegerType().ShouldBe(expectedResult);
type.IsNumericIntegerType(includeNullables: false).ShouldBe(expectedResult);

if (expectedResult)
{
var nullableType = typeof(Nullable<>).MakeGenericType(type);
nullableType.IsNumericIntegerType(includeNullables: false).ShouldBe(false);
nullableType.IsNumericIntegerType(includeNullables: true).ShouldBe(true);
}
}

[Theory]
Expand All @@ -89,7 +103,14 @@ public void Test_IsNumericIntegerType(Type type, bool expectedResult)
[InlineData(typeof(decimal), true)]
public void Test_IsNumericFloatType(Type type, bool expectedResult)
{
type.IsNumericFloatType().ShouldBe(expectedResult);
type.IsNumericFloatType(includeNullables: false).ShouldBe(expectedResult);

if (expectedResult)
{
var nullableType = typeof(Nullable<>).MakeGenericType(type);
nullableType.IsNumericFloatType(includeNullables: false).ShouldBe(false);
nullableType.IsNumericFloatType(includeNullables: true).ShouldBe(true);
}
}

[Fact]
Expand Down

0 comments on commit ed933b4

Please sign in to comment.