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 alloc-free params ReadOnlySpan<object?> overloads to .NET 9 #155

Merged
merged 1 commit into from
Dec 20, 2024
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
33 changes: 33 additions & 0 deletions src/Validation/Assumes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,20 @@ public static void False([DoesNotReturnIf(true)] bool condition, [Localizable(fa
}
}

#if NET9_0_OR_GREATER
/// <inheritdoc cref="False(bool, string, object?[])"/>
[DebuggerStepThrough]
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public static void False([DoesNotReturnIf(true)] bool condition, [Localizable(false)] string unformattedMessage, params ReadOnlySpan<object?> args)
{
if (condition)
{
Fail(Format(unformattedMessage, args));
}
}

#endif

/// <summary>
/// Throws an public exception if a condition evaluates to false.
/// </summary>
Expand Down Expand Up @@ -189,6 +203,21 @@ public static void True([DoesNotReturnIf(false)] bool condition, [Localizable(fa
}
}

#if NET9_0_OR_GREATER

/// <inheritdoc cref="True(bool, string, object?[])"/>
[DebuggerStepThrough]
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public static void True([DoesNotReturnIf(false)] bool condition, [Localizable(false)] string unformattedMessage, params ReadOnlySpan<object?> args)
{
if (!condition)
{
Fail(Format(unformattedMessage, args));
}
}

#endif

/// <summary>
/// Unconditionally throws an <see cref="InternalErrorException"/>.
/// </summary>
Expand Down Expand Up @@ -324,7 +353,11 @@ public static Exception Fail([Localizable(false)] string? message, Exception? in
/// <summary>
/// Helper method that formats string arguments.
/// </summary>
#if NET9_0_OR_GREATER
private static string Format(string format, params ReadOnlySpan<object?> arguments)
#else
private static string Format(string format, params object?[] arguments)
#endif
{
return PrivateErrorHelpers.Format(format, arguments);
}
Expand Down
7 changes: 7 additions & 0 deletions src/Validation/PrivateErrorHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@ internal static Type TrimGenericWrapper(Type type, Type? wrapper)
/// Helper method that formats string arguments.
/// </summary>
/// <returns>The formatted string.</returns>
#if NET9_0_OR_GREATER
internal static string Format(string format, params ReadOnlySpan<object?> arguments)
{
return string.Format(CultureInfo.CurrentCulture, format, arguments);
}
#else
internal static string Format(string format, params object?[] arguments)
{
return string.Format(CultureInfo.CurrentCulture, format, arguments);
}
#endif
}
}
82 changes: 82 additions & 0 deletions src/Validation/Requires.cs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,18 @@ public static void Argument([DoesNotReturnIf(false)] bool condition, string? par
}
}

#if NET9_0_OR_GREATER
/// <inheritdoc cref="Argument(bool, string?, string, object?[])"/>"
Copy link
Preview

Copilot AI Dec 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XML documentation tag has an extra double quote at the end. It should be removed.

Suggested change
/// <inheritdoc cref="Argument(bool, string?, string, object?[])"/>"
/// <inheritdoc cref="Argument(bool, string?, string, object?[])"/>

Copilot is powered by AI, so mistakes are possible. Review output carefully before use.

Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
[DebuggerStepThrough]
public static void Argument([DoesNotReturnIf(false)] bool condition, string? parameterName, string message, params ReadOnlySpan<object?> args)
{
if (!condition)
{
throw new ArgumentException(Format(message, args), parameterName);
}
}
#endif

/// <summary>
/// Throws an <see cref="ArgumentException"/> if a condition does not evaluate to true.
/// </summary>
Expand Down Expand Up @@ -440,6 +452,19 @@ public static void Argument([DoesNotReturnIf(false)] bool condition, string? par
}
}

#if NET9_0_OR_GREATER
/// <inheritdoc cref="Argument(bool, string?, ResourceManager, string, object?[])"/>
[DebuggerStepThrough]
public static void Argument([DoesNotReturnIf(false)] bool condition, string? parameterName, ResourceManager resourceManager, string unformattedMessageResourceName, params ReadOnlySpan<object?> args)
{
NotNull(resourceManager, nameof(resourceManager));
if (!condition)
{
throw new ArgumentException(Format(resourceManager, unformattedMessageResourceName, args), parameterName);
}
}
#endif

/// <summary>
/// Throws an ArgumentException.
/// </summary>
Expand All @@ -462,6 +487,16 @@ public static Exception Fail(string unformattedMessage, params object?[] args)
throw Fail(Format(unformattedMessage, args));
}

#if NET9_0_OR_GREATER
/// <inheritdoc cref="Fail(string, object?[])"/>
[DebuggerStepThrough]
[DoesNotReturn]
public static Exception Fail(string unformattedMessage, params ReadOnlySpan<object?> args)
{
throw Fail(Format(unformattedMessage, args));
}
#endif

/// <summary>
/// Throws an ArgumentException.
/// </summary>
Expand All @@ -473,6 +508,16 @@ public static Exception Fail(Exception? innerException, string unformattedMessag
throw new ArgumentException(Format(unformattedMessage, args), innerException);
}

#if NET9_0_OR_GREATER
/// <inheritdoc cref="Fail(Exception, string, object?[])"/>
[DebuggerStepThrough]
[DoesNotReturn]
public static Exception Fail(Exception? innerException, string unformattedMessage, params ReadOnlySpan<object?> args)
{
throw new ArgumentException(Format(unformattedMessage, args), innerException);
}
#endif

#if !NET35
/// <summary>
/// Throws an <see cref="InvalidEnumArgumentException"/> if a given value is not a named value of the enum type.
Expand Down Expand Up @@ -609,6 +654,35 @@ public static void ValidElements<T>([ValidatedNotNull] IEnumerable<T> values, Pr
}
}

#if NET9_0_OR_GREATER
/// <inheritdoc cref="ValidElements{T}(IEnumerable{T}, Predicate{T}, string?, string, object?[])"/>
[DebuggerStepThrough]
public static void ValidElements<T>([ValidatedNotNull] IEnumerable<T> values, Predicate<T> predicate, string? parameterName, string unformattedMessage, params ReadOnlySpan<object?> args)
{
// To whoever is doing random code cleaning:
// Consider the performance when changing the code to delegate to NotNull.
// In general do not chain call to another function, check first and return as early as possible.
if (values is null)
{
throw new ArgumentNullException(nameof(values));
}

if (predicate is null)
{
throw new ArgumentNullException(nameof(predicate));
}

foreach (T value in values)
{
if (!predicate(value))
{
throw new ArgumentException(PrivateErrorHelpers.Format(unformattedMessage, args), parameterName);
}
}
}

#endif

/// <summary>
/// Validates some expression describing the acceptable condition for an argument evaluates to true.
/// </summary>
Expand All @@ -627,12 +701,20 @@ public static void ValidState(bool condition, string message)
/// <summary>
/// Helper method that formats string arguments.
/// </summary>
#if NET9_0_OR_GREATER
private static string Format(string format, params ReadOnlySpan<object?> arguments)
#else
private static string Format(string format, params object?[] arguments)
#endif
{
return PrivateErrorHelpers.Format(format, arguments);
}

#if NET9_0_OR_GREATER
private static string Format(ResourceManager resourceManager, string resourceName, params ReadOnlySpan<object?> arguments)
#else
private static string Format(ResourceManager resourceManager, string resourceName, params object?[] arguments)
#endif
{
return Format(resourceManager.GetString(resourceName, CultureInfo.CurrentCulture) ?? $"Missing resource named {resourceManager}", arguments);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Validation/Validation.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net462</TargetFrameworks>
<TargetFrameworks Condition="'$(MSBuildRuntimeType)'=='Full'">$(TargetFrameworks);net35</TargetFrameworks>
<Title>Input and runtime validation</Title>
Expand Down
26 changes: 26 additions & 0 deletions src/Validation/Verify.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ public static void Operation([DoesNotReturnIf(false)] bool condition, string unf
}
}

#if NET9_0_OR_GREATER

/// <inheritdoc cref="Operation(bool, string, object?[])"/>
[DebuggerStepThrough]
public static void Operation([DoesNotReturnIf(false)] bool condition, string unformattedMessage, params ReadOnlySpan<object?> args)
{
if (!condition)
{
throw new InvalidOperationException(PrivateErrorHelpers.Format(unformattedMessage, args));
}
}

#endif

/// <summary>
/// Throws an <see cref="InvalidOperationException"/> if a condition is false.
/// </summary>
Expand Down Expand Up @@ -92,6 +106,18 @@ public static Exception FailOperation(string message, params object?[] args)
throw new InvalidOperationException(PrivateErrorHelpers.Format(message, args));
}

#if NET9_0_OR_GREATER

/// <inheritdoc cref="FailOperation(string, object?[])"/>
[DebuggerStepThrough]
[DoesNotReturn]
public static Exception FailOperation(string message, params ReadOnlySpan<object?> args)
{
throw new InvalidOperationException(PrivateErrorHelpers.Format(message, args));
}

#endif

/// <summary>
/// Throws an <see cref="ObjectDisposedException"/> if an object is disposed.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion test/Validation.Tests/Validation.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net472</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
Expand Down