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