-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Runtime
Milestone
Description
Background and motivation
While migrating code to start using ArgumentNullException.ThrowIfNull, I'm finding it cumbersome that there are no overloads for passing in nullable value types or pointers. This leads to code looking inconsistent because it uses a mix of ThrowIfNull and either custom throw helpers or conditionals, it feels like I'm still dealing with all the problems that ThrowIfNull was added to solve, just for pointers and value types instead of classes.
API Proposal
namespace System
{
public partial class ArgumentNullException : ArgumentException
{
/// <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>
public static unsafe void ThrowIfNull(void* argument, [CallerArgumentExpression("argument")] string? paramName = null);
/// <summary>Throws an <see cref="ArgumentNullException"/> if <paramref name="argument"/> is null.</summary>
/// <param name="argument">The argument to validate as non-null.</param>
/// <param name="paramName">The name of the parameter with which <paramref name="argument"/> corresponds.</param>
public static void ThrowIfNull<T>([NotNull] T? argument, [CallerArgumentExpression("argument")] string? paramName = null)
where T : struct;
}
}API Usage
public static int DereferenceSomePointer(int* pointer)
{
ArgumentNullException.ThrowIfNull(pointer);
return *pointer;
}
public static int DereferenceAnotherPointer(IntPtr pointer)
{
ArgumentNullException.ThrowIfNull((void*)pointer);
return *(int*)pointer;
}
public static int GetValueOfNullableInt(int? nullable)
{
ArgumentNullException.ThrowIfNull(nullable);
return nullable.Value;
}
[Flags]
public enum OperationFlags
{
None = 0,
RequireInt = 1 << 0
}
public static void PerformOperation(OperationFlags flags, int? integer = null)
{
if (flags.HasFlag(OperationFlags.RequireInt))
ArgumentNullException.ThrowIfNull(integer);
// perform operation
}Risks
- The
Nullable<T>overload could potentially result in a lot of generic instantiations. - The pointer overload is an
unsafemethod being exposed on an extremely common safe type. I'm not sure how the .NET team feels about this.
tannergooding, rickbrew, giladfrid009 and zmj
Metadata
Metadata
Assignees
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Runtime