有没有办法创建一个引用<T> <T> C# 中列表元素的跨度或内存<T>?



>显然我可以间接地这样做(例如,首先转换为数组),但我的目标是避免尽可能多的副本和分配。 最终,我想编写一个函数,该函数返回Memory<T>并从List<T>内部构造该对象。

只要您承诺不更改内存上操作之间的.Count值,并且从不执行任何会导致列表的内部数组被换出的操作,以下内容就可以了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace SandboxNetStandard
{
    public static class ListAdapter<T>
    {
        private static readonly FieldInfo _arrayField = typeof(List<T>)
            .GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
            .Single(x => x.FieldType == typeof(T[]));
        /// <summary>
        /// Converts
        /// <paramref name="listIPromiseToNotChangeTheCountOfAndNotCauseCapacityToChange"/>
        /// to an <see cref="Memory{T}"/>.
        /// </summary>
        /// <param name="listIPromiseToNotChangeTheCountOfAndNotCauseCapacityToChange">
        /// The list to convert.
        ///
        /// On each use of the returned memory object the list must have the same value of
        /// <see cref="List{T}.Count"/> as the original passed in value. Also between calls 
        /// you must not do any action that would cause the internal array of the list to
        /// be swapped out with another array.
        /// </param>
        /// <returns>
        /// A <see cref="Memory{T}"/> that is linked to the passed in list.
        /// </returns>
        public static Memory<T> ToMemory(
            List<T> listIPromiseToNotChangeTheCountOfAndNotCauseCapacityToChange)
        {
            Memory<T> fullArray = (T[]) _arrayField.GetValue(
                    listIPromiseToNotChangeTheCountOfAndNotCauseCapacityToChange);
            return fullArray.Slice(0,
                listIPromiseToNotChangeTheCountOfAndNotCauseCapacityToChange.Count);
        }
    }
}

最新更新