[英]Is there a away to convert IList<ArraySegment<byte>> to byte[] without enumerating through the List and adding to a new byte[]?
我了解我可以通过IList进行枚举,例如:
public byte[] ConvertToByteArray(IList<ArraySegment<byte>> list) {
IList<byte> newList = new List<byte>();
foreach(var asb in list) {
for ( int i = asb.Offset; i < (asb.Offset + asb .Count); i++ ) {
newList.Add(asb.Array[i]);
}
}
return newList.ToArray();
}
但这看起来很丑,有没有更好的方法呢?
这可以是一个潜在的棘手的问题,因为ArraySegment
实际上仅仅围绕原始阵列的图包装,并没有限制的数量ArraySegment
(一个或多个创建的周围排列的被存储为参考,不是副本,在ArraySegment.Array
属性)-因此,您不能ArraySegment.Array
提取数组来做任何技巧。
话虽如此,您的初始代码可以稍作改进。 缓冲副本。 假定您要使指向基础数组中相同值的段中的值在结果数组中重复。
public byte[] ConvertToByteArray(IList<ArraySegment<byte>> list)
{
var bytes = new byte[list.Sum (asb => asb.Count)];
int pos = 0;
foreach (var asb in list) {
Buffer.BlockCopy (asb.Array, asb.Offset, bytes, pos, asb.Count);
pos += asb.Count;
}
return bytes;
}
这样做确实在list
上进行了两次迭代(以获取总计数,但是对于更大的ArraySegments,在我的综合测试中,缓冲复制是一次成功,而不是额外的迭代是一次失败)。 与往常一样,测量其性能关键代码路径。
一次遇到同一问题时,我发现了这个很好的解释您的问题。 ( http://www.fotia.co.uk/fotia/DN.01.CoVariantGenericList.aspx )
通过创建从通用列表类继承的类并添加为我执行迭代的构造函数,我已经实现了您可能希望使用的代码类型。
public class bytes : List<byte>
{
public bytes()
{
}
public bytes (IList<ArraySegment<byte>> list)
{
for ( int i = 0; i < list.Count; i++ )
{
this.Add(asb.Array[i]);
}
}
}
然后,在您的代码中就可以拥有:
bytes myList = new bytes(yourIList);
这不会消除对转换的需求,但会隐藏代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.