我正在尝试在方法中创建一个现有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可以在这里共享底层数组。但 当仔细检查这个时,我看到实现没有:
2017年3月18日来自corefx/../ImmutableArray.cs at github的15757a8
/// <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);
}
为什么必须在此处制作基础项目的副本? 并不是这种方法的文档误导/错误?它说
此重载允许辅助方法或自定义构建器类 有效地避免为复制数组时支付多余的税 new array是现有数组的一部分。
但是分段情况正好在它复制时,如果所需的片是空的或整个输入数组,它只会避免复制。
是否还有另一种方法可以实现我想要的东西,而不是实现某种ImmutableArraySpan
?
答案 0 :(得分:2)
我将在评论的帮助下回答我自己的问题:
ImmutableArray不能代表底层数组的一个片段,因为它没有相应的字段 - 显然添加64/128位很少使用的范围字段会太浪费。
所以唯一可能的是拥有一个正确的Slice / Span结构,除了ArraySegment之外没有一个结构(不能使用ImmutableArray作为后备数据)。
编写一个实现IReadOnlyList<T>
等的ImmutableArraySegment可能很容易,因此这可能是解决方案。
关于文档 - 它尽可能正确,它避免了它可以的所有副本(全部,没有)和其他副本。
新的Span和ReadonlySpan类型的API将附带低级代码(ref return / locals)的神奇语言和运行时功能。这些类型实际上已作为System.Memory nuget包的一部分提供,但在它们被集成之前,将无法使用它们来解决在ImmutableArray上切片ImmutableArray的问题,而ImmutableArray需要这个方法(在System.Collections.Immutable中,它不依赖于System.Memory类型)
public ReadonlySpan<T> Slice(int start, int count)
我猜/希望一旦这些类型到位就会出现这样的API。