我试图在一种方法中切成一个现有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/

10-11 20:24