gpt4 book ai didi

c# - 为什么 ImmutableArray.Create 复制现有的不可变数组?

转载 作者:太空狗 更新时间:2023-10-29 23:36:23 24 4
gpt4 key购买 nike

我正在尝试对现有的 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);
}

为什么它必须在这里制作底层项目的副本?这种方法的文档不是误导性的/错误的吗?它说

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.

但是段的情况恰好是它复制的时候,它只会在所需的切片为空或整个输入数组时避免复制。

除了实现某种 ImmutableArraySpan 之外,还有其他方法可以完成我想要的吗? ?

最佳答案

我将借助评论回答我自己的问题:

ImmutableArray 不能表示底层数组的一部分,因为它没有对应的字段 - 显然,添加很少使用的 64/128 位范围字段太浪费了。

所以唯一的可能性是拥有一个合适的 Slice/Span 结构,目前除了 ArraySegment 之外没有其他的(它不能使用 ImmutableArray 作为支持数据)。

编写一个实现 IReadOnlyList<T> 的 ImmutableArraySegment 可能很容易等等,所以可能是这里的解决方案。

关于文档 - 它尽可能正确,它避免了尽可能少的副本(全部,没有)和其他副本。

有新的 API 和新的 Span 和 ReadonlySpan 类型,它们将为低级代码(ref 返回/本地)提供神奇的语言和运行时特性。这些类型实际上已经作为 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com