我试图在一种方法中切成一个现有ImmutableArray<T>
的切片,并认为我可以像这样使用Create<T>(ImmutableArray<T> a, int offset, int count)
的构造方法:
var arr = ImmutableArray.Create('A', 'B', 'C', 'D');
var bc ImmutableArray.Create(arr, 1, 2);
我希望我的两个ImmutableArrays可以在这里共享基础数组。但
当再次检查时,我发现该实现没有:
来自corefx/../ImmutableArray.cs at github在15757a8 2017年3月18日
/// <summary>
/// Initializes a new instance of the <see cref="ImmutableArray{T}"/> struct.
/// </summary>
/// <param name="items">The array to initialize the array with.
/// The selected array segment may be copied into a new array.</param>
/// <param name="start">The index of the first element in the source array to include in the resulting array.</param>
/// <param name="length">The number of elements from the source array to include in the resulting array.</param>
/// <remarks>
/// This overload allows helper methods or custom builder classes to efficiently avoid paying a redundant
/// tax for copying an array when the new array is a segment of an existing array.
/// </remarks>
[Pure]
public static ImmutableArray<T> Create<T>(ImmutableArray<T> items, int start, int length)
{
Requires.Range(start >= 0 && start <= items.Length, nameof(start));
Requires.Range(length >= 0 && start + length <= items.Length, nameof(length));
if (length == 0)
{
return Create<T>();
}
if (start == 0 && length == items.Length)
{
return items;
}
var array = new T[length];
Array.Copy(items.array, start, array, 0, length);
return new ImmutableArray<T>(array);
}
为什么必须在这里制作基础项目的副本?
而且该方法的文档是否具有误导性/错误性?它说
但是段大小写恰好是在复制时,并且仅在所需的切片为空或整个输入数组时才避免复制。
除了实现某种
ImmutableArraySpan
之外,还有另一种方法可以实现我想要的功能吗? 最佳答案
我将借助评论来回答我自己的问题:
ImmutableArray无法表示基础数组的一部分,因为它没有用于其的字段-显然,添加64/128位范围字段(很少使用)会太浪费。
因此,唯一的可能性就是拥有一个适当的Slice/Span结构,并且除了ArraySegment(目前无法使用ImmutableArray作为后备数据)之外,目前没有其他结构。
编写实现IReadOnlyList<T>
等的ImmutableArraySegment可能很容易,因此这里可能是解决方案。
关于文档-它是尽可能正确的,它避免了可能的所有副本(全部,没有副本),否则进行了副本。
有一些新的API具有新的Span和ReadonlySpan类型,它们将附带神奇的语言和运行时功能以实现低级代码(引用返回/本地),这些类型实际上已经作为System.Memory nuget包的一部分提供了,但是直到它们已经集成在一起,将无法使用它们来解决对ImmutableArray进行切片的问题,该问题需要在ImmutableArray上使用此方法(位于System.Collections.Immutable中,该方法不依赖于System.Memory类型)
public ReadonlySpan<T> Slice(int start, int count)
我猜测/希望一旦类型到位,此类API就会出现。
关于c# - 为什么ImmutableArray.Create复制现有的不可变数组?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46831531/