有没有任何方法(可能是肮脏的黑客)来创建一个ImmutableArray,它只使用指定的数组,而不是复制它?
我有一个我知道不会改变的数组,我想创建一个ImmutableArray来允许客户端安全地访问我的数组。
查看ImmutableArray的源代码,我看到Create方法没有帮助:
public static ImmutableArray<T> Create<T>(params T[] items)
{
if (items == null)
{
return Create<T>();
}
// We can't trust that the array passed in will never be mutated by the caller.
// The caller may have passed in an array explicitly (not relying on compiler params keyword)
// and could then change the array after the call, thereby violating the immutable
// guarantee provided by this struct. So we always copy the array to ensure it won't ever change.
return CreateDefensiveCopy(items);
}编辑:在GitHub上有一个关于这个特性的请求,这也给出了使用最快的黑客:https://github.com/dotnet/corefx/issues/28064
发布于 2018-07-12 09:15:45
还有另外两种方法,这两种方法都是在这里建议的:https://stackoverflow.com/a/3799030/4418060 (一个在答复中,一个在评论中)。
首先,创建一个新的struct类型,它反映ImmutableArray的布局(这是一个T[]字段),并更改该结构的类型,如CLR (运行时)所见。结构将如下所示:
public struct HackImmutableArray<T>
{
public T[] Array;
}Unsafe中可用的System.Runtime.CompilerServices.Unsafe NuGet静态类
使用System.Runtime.CompilerServices;静态ImmutableArray HackyMakeImmutable(T[]数组){返回Unsafe.As(ref数组);}第二个选项是“不安全”,但非常安全,因为我们可以肯定地假定ImmutableArray的结构布局不会改变,这是一个定义特性,而且它可能比任何其他解决方案都快得多。
发布于 2018-07-12 08:01:54
如果您知道数组的确切长度,则可以使用ImmutableArray.CreateBuilder<>加上将从Builder内部创建ImmutableArray<>的.MoveToImmutable(),而无需复制它:
var builder = ImmutableArray.CreateBuilder<int>(4);
builder.Add(1);
builder.Add(2);
builder.Add(3);
builder.Add(4);
ImmutableArray<int> array = builder.MoveToImmutable();方法.MoveToImmutable()将引发异常,如果builder.Capacity != builder.Count
注意,构建器的其他方法(如.ToImmutable())将创建数组的副本。
发布于 2018-07-12 09:14:06
在https://github.com/dotnet/corefx/issues/28064,他们推荐最快的方法是使用System.Runtime.CompilerServices.Unsafe:
ImmutableArray<T> im = Unsafe.As<T[], ImmutableArray<T>>(ref array);https://stackoverflow.com/questions/51300066
复制相似问题