有什么方法可以创建引用C#中List <t>的元素的Span <t>或Memory <t>?

时间:2019-02-03 22:06:01

标签: c#

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

1 个答案:

答案 0 :(得分:3)

只要您保证不更改内存操作之间的.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);
        }
    }
}