有没有办法创建一个跨度<;T>;或记忆<;T>;指列表中的元素<;T>;在C#中?
显然,我可以间接地这样做(例如首先转换为数组),但我的目标是尽可能避免复制和分配。最终,,我想写一个函数,返回一个有没有办法创建一个跨度<;T>;或记忆<;T>;指列表中的元素<;T>;在C#中?,c#,C#,显然,我可以间接地这样做(例如首先转换为数组),但我的目标是尽可能避免复制和分配。最终,,我想写一个函数,返回一个内存,并从列表内部构造该对象,只要您保证在内存上的操作之间不更改.Count的值,并且决不执行任何会导致列表内部数组被交换的操作工作 using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace SandboxNetStandard {
内存
,并从列表
内部构造该对象,只要您保证在内存上的操作之间不更改.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);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
运用系统反思;
命名空间SandboxNetStandard
{
公共静态类ListAdapter
{
私有静态只读字段信息_arrayField=typeof(列表)
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
.Single(x=>x.FieldType==typeof(T[]);
///
///皈依
///
///到。
///
///
///要转换的列表。
///
///每次使用返回的内存对象时,列表的值必须相同
///作为原始传入值。也是在调用之间
///您不能执行任何会导致列表的内部数组丢失的操作
///可以与另一个阵列交换。
///
///
///链接到传入列表的。
///
公共静态存储器(
列表I未更改未导致容量更改的原因)
{
内存已满数组=(T[])\u arrayField.GetValue(
上市公司不得更改账户(不得导致产能变更);
返回fullArray.Slice(0,
LISTIP ROMISE不更改计数器,也不导致容量更改。计数);
}
}
}
无论您使用什么解决方案,它都不会再链接到列表,因为随着列表大小的增加,列表不再使用相同的数组。在转换过程中,至少会产生一个内存拷贝。我能看到的唯一警告是,如果您使用反射来获取列表的内部T[]
,但该引用只有在列表执行调整大小操作之前才有效。在我的情况下,调整大小不是问题。基本上,我正在优化一种可以在各种数据结构上运行的通用算法。我需要一种在不知道数据结构是什么的情况下有效访问数据结构中的值的方法。我还有其他方法可以做到这一点,但是内存似乎特别干净(如果可以的话)。(在一个特定的情况下,结构内部包含List对象——这就是问题所在。)如果我将其复制到项目中,我几乎不会更改该参数名称=P说真的,我认为这种调整尺寸的担忧有点言过其实。也许这是我的C++背景会话,但是我可以用一个方法返回数据,该方法只有在修改源代码时才有效(只要它被正确记录)。