I really like ArgumentNullException.ThrowIf(...)
and ArgumentException.ThrowIfNullOrEmpty(...)
and there are upcoming ones in .NET 8, so until then I created a ThrowHelper on my own. Could you please review it and tell me your opinion? Can something be improved?
public static class Assertions
{
public static void ThrowIfNull<T>([NotNull] T? value, string? paramName = null, string message = "Parameter cannot be null.") where T : class
{
if (value == null)
{
ThrowArgumentNullException(paramName, message);
}
}
public static void ThrowIfNullOrEmpty(string value, string? paramName = null, string message = "String cannot be empty.")
{
if (string.IsNullOrEmpty(value))
{
ThrowArgumentException(paramName, message);
}
}
public static void ThrowIfNullOrEmpty<T>([NotNull] ICollection<T>? collection, string? paramName = null, string message = "Collection must have elements.")
{
if (collection == null || !collection.Any())
{
ThrowArgumentException(paramName, message);
}
}
public static void ThrowIfNullOrEmpty<T>([NotNull] T[]? array, string? paramName = null, string message = "Array must have elements.")
{
if (array == null || array.Length == 0)
{
ThrowArgumentException(paramName, message);
}
}
public static void ThrowIfNullOrWhiteSpace(string value, string? paramName = null, string message = "String cannot be empty or whitespace.")
{
if (string.IsNullOrWhiteSpace(value))
{
ThrowArgumentException(paramName, message);
}
}
public static void ThrowIfOutOfRange<T>(T value, T minValue, T maxValue, string? paramName = null, string message = "Value must be within the specified range.") where T : IComparable<T>
{
if (value.CompareTo(minValue) < 0 || value.CompareTo(maxValue) > 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfLessThan<T>(T value, T threshold, string? paramName = null, string message = "Value must be greater than or equal to the threshold.") where T : IComparable<T>
{
if (value.CompareTo(threshold) < 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfLessThanOrEqualTo<T>(T value, T threshold, string? paramName = null, string message = "Value must be greater than the threshold.") where T : IComparable<T>
{
if (value.CompareTo(threshold) <= 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfGreaterThan<T>(T value, T threshold, string? paramName = null, string message = "Value must be less than the threshold.") where T : IComparable<T>
{
if (value.CompareTo(threshold) > 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfGreaterThanOrEqualTo<T>(T value, T threshold, string? paramName = null, string message = "Value must be less than or equal to the threshold.") where T : IComparable<T>
{
if (value.CompareTo(threshold) >= 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfEqual<T>(T value, T target, string? paramName = null, string message = "Parameter cannot be equal to its default value.")
{
if (EqualityComparer<T>.Default.Equals(value, target))
{
ThrowArgumentException(paramName, message);
}
}
[DoesNotReturn]
private static void ThrowArgumentException(string? paramName, string message) => throw new ArgumentException(message, paramName);
[DoesNotReturn]
private static void ThrowArgumentOutOfRangeException(string? paramName, string message) => throw new ArgumentOutOfRangeException(paramName, message);
[DoesNotReturn]
private static void ThrowArgumentNullException(string? paramName, string message) => throw new ArgumentNullException(paramName, message);
}
Modifications based on slepic's comment
using System.Diagnostics.CodeAnalysis;
namespace GridBot.Api.Extensions;
public static class Assertions
{
public static void ThrowIfNull<T>([NotNull] T? argument, string? paramName = null, string message = "Parameter cannot be null.") where T : class
{
if (argument == null)
{
ThrowArgumentNullException(paramName, message);
}
}
public static void ThrowIfNullOrEmpty(string argument, string? paramName = null, string message = "String cannot be empty.")
{
if (string.IsNullOrEmpty(argument))
{
ThrowNullOrEmptyException(argument, paramName, message);
}
}
public static void ThrowIfNullOrEmpty<T>([NotNull] ICollection<T>? argument, string? paramName = null, string message = "Collection must have elements.")
{
if (argument == null || !argument.Any())
{
ThrowArgumentException(paramName, message);
}
}
public static void ThrowIfNullOrEmpty<T>([NotNull] T[]? argument, string? paramName = null, string message = "Array must have elements.")
{
if (argument == null || argument.Length == 0)
{
ThrowArgumentException(paramName, message);
}
}
public static void ThrowIfNullOrWhiteSpace(string argument, string? paramName = null, string message = "String cannot be empty or whitespace.")
{
if (string.IsNullOrWhiteSpace(argument))
{
ThrowArgumentException(paramName, message);
}
}
public static void ThrowIfOutOfRange<T>(T argument, T minValue, T maxValue, string? paramName = null, string message = "Value must be within the specified range.") where T : IComparable<T>
{
if (argument.CompareTo(minValue) < 0 || argument.CompareTo(maxValue) > 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfLessThan<T>(T argument, T threshold, string? paramName = null, string message = "Value must be greater than or equal to the threshold.") where T : IComparable<T>
{
if (argument.CompareTo(threshold) < 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfLessThanOrEqualTo<T>(T argument, T threshold, string? paramName = null, string message = "Value must be greater than the threshold.") where T : IComparable<T>
{
if (argument.CompareTo(threshold) <= 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfGreaterThan<T>(T argument, T threshold, string? paramName = null, string message = "Value must be less than the threshold.") where T : IComparable<T>
{
if (argument.CompareTo(threshold) > 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfGreaterThanOrEqualTo<T>(T argument, T threshold, string? paramName = null, string message = "Value must be less than or equal to the threshold.") where T : IComparable<T>
{
if (argument.CompareTo(threshold) >= 0)
{
ThrowArgumentOutOfRangeException(paramName, message);
}
}
public static void ThrowIfEqual<T>(T argument, T target, string? paramName = null, string message = "Parameter cannot be equal to its default value.")
{
if (EqualityComparer<T>.Default.Equals(argument, target))
{
ThrowArgumentException(paramName, message);
}
}
[DoesNotReturn]
private static void ThrowNullOrEmptyException([NotNull] string? argument, string? paramName, string message)
{
ThrowIfNull(argument, paramName, message);
throw new ArgumentException(message, paramName);
}
[DoesNotReturn]
private static void ThrowArgumentException(string? paramName, string message) => throw new ArgumentException(message, paramName);
[DoesNotReturn]
private static void ThrowArgumentOutOfRangeException(string? paramName, string message) => throw new ArgumentOutOfRangeException(paramName, message);
[DoesNotReturn]
private static void ThrowArgumentNullException(string? paramName, string message) => throw new ArgumentNullException(paramName, message);
}
ArgumentException.ThrowIfNullOrEmpty
and in fact they doArgumentNullException.ThrowIfNull(argument, paramName); throw new ArgumentException(SR.Argument_EmptyString, paramName);
\$\endgroup\$ThrowIfNullOrWhiteSpace
should be done in a similar fashion. Or why you don't just post it as an answer \$\endgroup\$ThrowIfNullOrEmpty<T>([NotNull] ICollection<T>? argument
andThrowIfNullOrEmpty<T>([NotNull] T[]? argument
? \$\endgroup\$