Use Span<T> as C# class level variable

643 Views Asked by At

I'm writing a high-performance parser for a comma delimited stream (network). My goal is to parse and convert directly from binary to dotnet primitives. Based on my testing thus far, Span performance is incredible, but the type is difficult to work with due to restrictions inherent to ref structs. I've hit a roadblock trying to find an efficient way to store Span constants (comma, newline, etc.) used throughout my application. The only solution that seems to exist to store them as byte and convert them in the class bodies of methods...or hardcode Span<byte> delimiter = Encoding.UTF8.GetBytes("\r\n") in every method body.

The following is what I'd like to achieve but it gives the error - `CS8345 Field or auto-implemented property cannot be of type 'Span' unless it is an instance member of a ref struct.

public class Parser
{
    Span<byte> NewLine = new byte[]{ (byte)'\n' };
}

There's got to be a better way! Please help!

1

There are 1 best solutions below

2
Guru Stron On

You can create ReadOnlySpan<byte> with UTF-8 literal in .NET 7:

class Consts
{
    public static ReadOnlySpan<byte> Delim => "\n"u8;
}

Or use Memory/ReadOnlyMemory:

public class Consts 
{
    public static ReadOnlyMemory<int> Type { get; } = new []{1};
}

And usage:

ReadOnlySpan<int> span = Consts.Type.Span;

Or decorate aforementioned approach into method/expression bodied property:

class Consts
{
    private static readonly byte[] _delim = { (byte)'\n' };
    public static ReadOnlySpan<byte> Delim => _delim;
}

Demo