Skip to content

Commit

Permalink
Add ThrowIfNull overload for pointers (#61633)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub committed Nov 18, 2021
1 parent 6ff57f1 commit b11bda2
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ public static void ThrowIfNull([NotNull] object? argument, [CallerArgumentExpres
}
}

/// <summary>Throws an <see cref="ArgumentNullException"/> if <paramref name="argument"/> is null.</summary>
/// <param name="argument">The pointer argument to validate as non-null.</param>
/// <param name="paramName">The name of the parameter with which <paramref name="argument"/> corresponds.</param>
[CLSCompliant(false)]
public static unsafe void ThrowIfNull([NotNull] void* argument, [CallerArgumentExpression("argument")] string? paramName = null)
{
if (argument is null)
{
Throw(paramName);
}
}

[DoesNotReturn]
private static void Throw(string? paramName) =>
throw new ArgumentNullException(paramName);
Expand Down
2 changes: 2 additions & 0 deletions src/libraries/System.Runtime/ref/System.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ public ArgumentNullException(string? paramName) { }
public ArgumentNullException(string? message, System.Exception? innerException) { }
public ArgumentNullException(string? paramName, string? message) { }
public static void ThrowIfNull([System.Diagnostics.CodeAnalysis.NotNullAttribute] object? argument, [System.Runtime.CompilerServices.CallerArgumentExpressionAttribute("argument")] string? paramName = null) { throw null; }
[System.CLSCompliant(false)]
public static unsafe void ThrowIfNull([System.Diagnostics.CodeAnalysis.NotNullAttribute] void* argument, [System.Runtime.CompilerServices.CallerArgumentExpressionAttribute("argument")] string? paramName = null) { throw null; }
}
public partial class ArgumentOutOfRangeException : System.ArgumentException
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,29 +49,37 @@ public static void Ctor_String_String()
}

[Fact]
public static void ThrowIfNull_NonNull_DoesntThrow()
public static unsafe void ThrowIfNull_NonNull_DoesntThrow()
{
foreach (object o in new[] { new object(), "", "argument" })
{
ArgumentNullException.ThrowIfNull(o);
ArgumentNullException.ThrowIfNull(o, "paramName");
}

int i = 0;
ArgumentNullException.ThrowIfNull(&i);
ArgumentNullException.ThrowIfNull(&i, "paramName");
}

[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData("name")]
public static void ThrowIfNull_Null_ThrowsArgumentNullException(string paramName)
public static unsafe void ThrowIfNull_Null_ThrowsArgumentNullException(string paramName)
{
AssertExtensions.Throws<ArgumentNullException>(paramName, () => ArgumentNullException.ThrowIfNull(null, paramName));
AssertExtensions.Throws<ArgumentNullException>(paramName, () => ArgumentNullException.ThrowIfNull((object)null, paramName));
AssertExtensions.Throws<ArgumentNullException>(paramName, () => ArgumentNullException.ThrowIfNull((void*)null, paramName));
}

[Fact]
public static void ThrowIfNull_UsesArgumentExpression()
public static unsafe void ThrowIfNull_UsesArgumentExpression()
{
object something = null;
AssertExtensions.Throws<ArgumentNullException>(nameof(something), () => ArgumentNullException.ThrowIfNull(something));
object someObject = null;
AssertExtensions.Throws<ArgumentNullException>(nameof(someObject), () => ArgumentNullException.ThrowIfNull(someObject));

byte* somePointer = null;
AssertExtensions.Throws<ArgumentNullException>(nameof(somePointer), () => ArgumentNullException.ThrowIfNull(somePointer));
}
}
}

0 comments on commit b11bda2

Please sign in to comment.