在深入研究问题之前,请理解,我不能控制整个食物链 - 对“你做错了”的回答或评论将无济于事,因为我需要反对给定的API。
传递原始数据块的组件,通常通过byte[]
或ArraySegment<byte>
类型的缓冲区进行传递。后者具有能够一劳永逸地分配大缓冲区的大优势,然后通过ArraySegment机制使用它的一部分来减少内存分配,碎片和GC问题。这里没什么新鲜的。
这是有代价的:消耗ArraySegment<byte>
的一个(可能是外来的,闭源的)组件获得对完整数组的引用(并因此访问),这意味着,如果它行为不端,它具有该能力破坏完全不相关的缓冲区。
现在:
System.Array
。System.ArraySegment<T>
。我的问题链是(回答一个人过时的问题):
byte[]
呈现给(外国)消费者ArraySegment<byte>
呈现给(外部)使用者,不会暴露完整的基础数组System.Array
,我错过了byte[]
,我已经错过了,如果它是GCed则不会搞砸修改
从我的评论中,我没有表达得足够明确。来回复制数据不是解决方案。这是我现在使用的拐杖。
答案 0 :(得分:0)
修改:为了澄清,您的选项是
T[]
/ ArraySegment<T>
编辑2:毫无疑问
是否有一种“棘手”的方式将自行开发的包装器作为byte []呈现给(外国)消费者
不,你不能这样做。
或者是否有一种“棘手”的方式将自行开发的包装器作为ArraySegment呈现给(外部)使用者,不会暴露完整的底层数组
不,你不能这样做。
另外,有没有办法继承System.Array,我错过了
不,你不能这样做。
再次交替:有没有办法从一个分配的(和固定的)内存区域创建一个byte [],我已经错过了,如果它是GCed那就不会搞砸了
不,你不能这样做。
如果没有更改外部API,这将成为原始答案:
如果您使用数组并且希望阻止其他代码访问允许范围之外的数组部分,则必须执行以下操作:
T[] originalData = ...;
int viewStart = ...;
int viewLength = ...;
// use a separate array for the viewable region
T[] view = new T[viewLength];
Array.Copy(originalData, viewStart, view, 0, viewLength);
ArraySegment<T> segment = new ArraySegment<T>(view).
// call other code
...
// apply changes
Array.Copy(view, 0, originalData, viewStart, viewLength);
由于API设计人员选择使用T[]
/ ArraySegment<T>
代替IList<T>
,因此您受到限制。