Background and motivation
While working on a generic-class, that accepts both classes and structs, I noticed that 'ArgumentNullException.ThrowIfNull' performs a boxing-operation by converting the passed-variable to 'object?'.
The immediate notice is that all structs are boxed but, a seemingly unintended side-effect, is that 'struct?' is also boxed if its not null.
I would like to propose using generic-method functionality instead. This would shave the unnecessary boxing operations, for struct and 'struct?', which could be expensive.
API Proposal
namespace System;
public class ArgumentNullException : ArgumentException
{
// SNIPPED
public static void ThrowIfNull<T>([NotNull] T? argument, [CallerArgumentExpression("argument")] string? paramName = null)
{
if (argument is null)
{
Throw(paramName);
}
}
// SNIPPED
}
API Usage
// Under the current-API, these will be boxed
int valueStruct = 25;
int? maybeNullStruct = 30;
// Under the current-API, this will not be boxed
int? definitelyNullStruct = null;
// When using the *new-API* ThrowIfNull<T>, none of these will be boxed
ArgumentNullException.ThrowIfNull(valueStruct);
ArgumentNullException.ThrowIfNull(maybeNullStruct);
ArgumentNullException.ThrowIfNull(definitelyNullStruct);
Alternative Designs
Creation of a separate-API, ArgumentNullException.ThrowGenericIfNull:
namespace System;
public class ArgumentNullException : ArgumentException
{
// SNIPPED
public static void ThrowGenericIfNull<T>([NotNull] T? argument, [CallerArgumentExpression("argument")] string? paramName = null)
{
if (argument is null)
{
Throw(paramName);
}
}
// SNIPPED
}
Risks
Before making this issue, I looked extensively for resources showing the costs of generics and boxing; and could not find anything showing generic-methods being a worse option. However I also am not working directly on the runtime. Nor am I staring at C# every waking hour… Well I do actually, but you get what I mean.
There is the possibility of a performance-regression if my knowledge of the situation wasn’t sufficient.
I’ve also noticed that the runtime sparingly uses generic-methods in non-generic classes. This may be a styling-guideline not mentioned in the contribution-guide.
There is the possibility of a styling-conflict, that wasn’t explicitly mentioned prior.
Background and motivation
While working on a generic-class, that accepts both classes and structs, I noticed that 'ArgumentNullException.ThrowIfNull' performs a boxing-operation by converting the passed-variable to 'object?'.
The immediate notice is that all structs are boxed but, a seemingly unintended side-effect, is that 'struct?' is also boxed if its not null.
I would like to propose using generic-method functionality instead. This would shave the unnecessary boxing operations, for struct and 'struct?', which could be expensive.
API Proposal
API Usage
Alternative Designs
Creation of a separate-API, ArgumentNullException.ThrowGenericIfNull:
Risks
Before making this issue, I looked extensively for resources showing the costs of generics and boxing; and could not find anything showing generic-methods being a worse option. However I also am not working directly on the runtime. Nor am I staring at C# every waking hour… Well I do actually, but you get what I mean.
There is the possibility of a performance-regression if my knowledge of the situation wasn’t sufficient.
I’ve also noticed that the runtime sparingly uses generic-methods in non-generic classes. This may be a styling-guideline not mentioned in the contribution-guide.
There is the possibility of a styling-conflict, that wasn’t explicitly mentioned prior.