Add support for Nullable structures to Span and Memory types
AlexRadch opened this issue · comments
Overview
Unfortunately, in .NET, Nullable structures currently do not have interfaces. However, the most useful methods for Span require that elements support the IEquatable and IComparable interfaces. Therefore, Span does not support Nullable structures well. At the same time, ordinary arrays perfectly support such structures.
I propose to add support for Nullable structures to spans by adding a wrapper for Nullable structures similar to the Box wrapper. This wrapper for the Nullable structure will support the IEquatable and IComparable interfaces.
I propose adding support for Nullable structures to Spans by adding a wrapper for the Nullable structure similar to the Box wrapper. This wrapper for the Nullable structure will support the IEquatable and IComparable interfaces.
Instances of our wrapper will not be created, the usual Nullable structure will always be created, but our wrapper will be needed to conveniently convert spans to Spans with our wrapper, and all span methods based on these interfaces will become available.
The same goes for the memory class. But less useful because the Memory class returns a Span, which we can already cast to a Span with the suggested wrapper.
API breakdown
public static NullableWraper<T> : IEquatable<NullableWraper<T>>, IComparable<NullableWraper<T>>
where T as in Nullable<T>
{
// Fields as inside Nullable<T> struct
// Interface implementation
// Implicit and Explicit casting methods
}
public static class SpanExtensions
{
// Add Span casting methods
}
Usage example
int?[] array = [9, 1, null, 3, null, 5, null, 7, null];
var span = array.AsSpan();
// The following line of code is not supported by Span methods because Nullable<T> does not have an IEquatable interface.
// var index = span.IndexOf(5);
// Casting to span with Nullable proxy
var smartSpan = span.WithNullableWraper();
// It works now!!!
var index = smartSpan.IndexOf(5);
Breaking change?
No
Alternatives
I do not not.
Additional context
No response
Help us help you
Yes, I'd like to be assigned to work on this item
Box<T>
relies on runtime implementation details and involves undefined behavior, it will most likely be deprecated and removed soon. The proposed NullableWrapper<T>
similarly relies on runtime implementation details so I don't think it's the right solution for this problem.
Agreed, we should not add any new APIs relying on implementation behavior of the runtime. The proposed API is doing exactly that, by relying on the internal layout of Nullable<T>
, and also on the runtime actually applying the same ordering on both types. Furthermore, this limitation really only affects an extremely niche scenario, and I can't say I've ever seen anyone else bringing this up, so we'd want more use case scenarios first. Even then, this feels more like something to fix in the BCL than here.
Thank you!