c# конверт Memory<char> в Memory<byte>

129
14 января 2021, 07:40

Нужно получить Memory<byte> из string без создания промежуточных массивов.

Для Span все просто

 var text = "Hello";
 var charSpan = text.AsSpan();
 var bytesSpan = MemoryMarshal.AsBytes(charSpan);

Но для Memory только часть пути

 var text = "Hello";
 var charMemory = text.AsMemory();
 а дальше????
Answer 1

Например так (требует разрешения unsafe-кода):

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Buffers;
namespace CilBytecodeParserTest
{
    class Program
    {
        unsafe class StringMemoryManager<T> : MemoryManager<T>
        {
            MemoryHandle h;            
            int len;
            public StringMemoryManager(string s)
            {                
                h = s.AsMemory().Pin();               
                len = s.Length * 2;
            }
            public override Span<T> GetSpan()
            {                
                return new Span<T>(h.Pointer, len/Marshal.SizeOf(typeof(T)));
            }
            public override MemoryHandle Pin(int elementIndex = 0)
            {
                return h; //useless
            }
            public override void Unpin()
            {
                //useless
            }
            protected override void Dispose(bool disposing)
            {
                if(disposing) h.Dispose();
            }
        }
        static void Main(string[] args)
        {
            string text = "Hello";  
            var mngr = new StringMemoryManager<byte>(text);
            Memory<byte> mem = mngr.Memory;
        }
    }
}

MemoryHandle позволяет получить указатель для любого Memory. MemoryManager создает Memory на основе любого Span, а Span можно создать из указателя. Получается универсальный конвертор всего во все. Недостаток в том, что строка будет закреплена в памяти на все время работы с нею. Если же вы спрашиваете, как сделать это нормально (без низкоуровневых хаков), то, видимо, никак. Не нашел такого API.

READ ALSO
C# BindingSource Combobox данные из другой таблицы

C# BindingSource Combobox данные из другой таблицы

В С# + MS SQL через ADONET есть так скажем 2 таблицы:

123
Контроль скорости Vector2

Контроль скорости Vector2

Делаю игру типа понга, шарик отталкивается от коллайдера за счёт "Bounciness = 1" динамический RigidbodyВозникла проблема, что в зависимости от угла...

101
Вывести Объекты класса ASP.NET Core

Вывести Объекты класса ASP.NET Core

Создал по шаблонам простое RestApi приложение,у меня есть классы User и Award и их контексты соответственно, объекты класса User я легко вывожу на хост,...

115