繁体   English   中英

是否有转换IList的方法 <ArraySegment<byte> &gt;到byte []而不通过列表枚举并添加到新的byte []吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM