I was porting some older high-speed C++ code to C#, and the existing code made use of a pointer-based double-indirection pattern like this (written here in a C# syntax), using the stack as efficient temporary storage:
public struct Source {
public byte* Start;
public int Count;
}
public struct SourceSet {
public Source* Start;
public int Count;
}
Source* sources = stackalloc Source[n*k];
SourceSet* sourceSets = stackalloc SourceSet[n];
It populates the sources
with sets of segments of the data, and populates the sourceSets
with how many Source
s are in each set.
The code works fine, but ideally, I would like to convert it to no longer use pointers and unsafe
— to instead use something memory-safe like this, where each SourceSet
would be populated by a .Slice()
of the sources:
public struct Source {
public int Start;
public int Count;
}
Span<Source> sources = stackalloc Source[n*k];
Span<Span<Source>> sourceSets = stackalloc Span<Source>[n];
But I can't write that, because Span<Span<T>>
can't exist in C# — Span<T>
is a ref struct
and thus can't be used as the type parameter of another Span<T>
. And I can't use Memory<Memory<T>>
as a replacement, because stackalloc
only produces a Span<T>
(or a pointer, but the goal is to avoid pointers).
(And yes, I understand that Span<Span<T>>
will likely never be added to the language, because it could potentially allow the rules about span lifetimes to be violated.)
So what's a good, efficient equivalent in C# for safe double-pointer indirection on the stack, something like Span<Span<T>>
, but that actually exists?
Try
Span2D<T>
: