我正在解析一个任意长度的字节数组,它将被传递给几个不同的解析层.每个解析器都像普通封装一样创建Header和Packet有效负载. 我的问题在于封装如何保持其包字节数组有效负载.假设我
我的问题在于封装如何保持其包字节数组有效负载.假设我有一个包含三级封装的100字节数组.将创建三个数据包对象,我想将这些数据包的有效负载设置为数据包字节数组中的相应位置.
例如,假设所有级别的有效负载大小都是20,那么可以想象它在每个对象上都有一个公共字节[] Payload.但是,问题是这个byte [] Payload是原始100字节的副本,所以我最终会在内存中使用160字节而不是100字节.
如果它在C中,我可以很容易地使用指针 – 但是,我在C#中写这个.
所以我创建了以下类:
public class PayloadSegment<T> : IEnumerable<T> { public readonly T[] Array; public readonly int Offset; public readonly int Count; public PayloadSegment(T[] array, int offset, int count) { this.Array = array; this.Offset = offset; this.Count = count; } public T this[int index] { get { if (index < 0 || index >= this.Count) throw new IndexOutOfRangeException(); else return Array[Offset + index]; } set { if (index < 0 || index >= this.Count) throw new IndexOutOfRangeException(); else Array[Offset + index] = value; } } public IEnumerator<T> GetEnumerator() { for (int i = Offset; i < Offset + Count; i++) yield return Array[i]; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { IEnumerator<T> enumerator = this.GetEnumerator(); while (enumerator.MoveNext()) { yield return enumerator.Current; } } }
这样我可以简单地引用原始字节数组中的位置,但使用位置索引.但是,如果我这样做:
PayloadSegment<byte> something = new PayloadSegment<byte>(someArray, 5, 10); byte[] somethingArray = something.ToArray();
将somethingArray作为字节的副本,还是对原始PayloadSegment的引用(后者又是对原始字节数组的引用)?
编辑:实际上在重新思考之后,我不能简单地使用新的MemoryStream(数组,偏移量,长度)吗?
Enumerable.ToArray扩展方法的文档没有具体提到当它传递一个恰好已经是数组的序列时它的作用.但是使用.NET Reflector进行的简单检查表明它确实创建了数组的副本.然而值得注意的是,当给定实现ICollection< T>的序列时. (数组所做的)复制可以更快地完成,因为元素的数量是预先知道的,因此它不必动态调整缓冲区的大小,例如List< T>.确实.