2014-11-15 51 views
1

說我有一個這樣的數組:迭代通過一個字節數組像它的標記Uint16 []

byte[] arr = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88} 

我可以採用某種遍歷它與像標記Uint16處理元素?我想讓我的應用程序像{0x1122, 0x3344, 0x5566, 0x7788}一樣對待它。

使用as關鍵字嘗試,但編譯器woudn't讓我:

byte[] bytearray = new byte[10]; 
UInt16[] uint16array = bytearray as UInt16[]; 

有沒有辦法做到這一點? (沒有創建另一個數組或在每次迭代中將兩個字節轉換爲一個uint16)

回答

1

這個小幫手方法可以幫助你

public static class helper 
{ 
    public static UInt16[] ToUnit16(this byte[] arr) 
    { 
     if (arr == null) 
      return null; 

     var len = arr.Length; 

     if ((len % 2) != 0) 
      throw new ArgumentException("Must divide by 2"); 

     var count = len/2; 

     var result = new UInt16[count]; 
     do 
     { 
      result[--count] = (UInt16)((arr[--len]) | arr[--len] << 8); 
     } while (count > 0); 

     return result; 
    } 
} 
1

不,C#不提供安全地重新解釋一個對象的方式,就好像它是某種不同類型的對象一樣(可以使用不安全的代碼,但是隨後整個裝配結束了「不安全」)。

可以使用BitConverter.ToUInt16(),或甚至在MemoryStream包住byte[]並使用BinaryReader.ReadUInt16()方法從字節[]對象來讀取。但從問題的措辭來看,你不想使用任何這樣的方法。

+0

將其轉換,您必須在解決BitConverter.IsLittleEndian – Fredou

+0

是的,字節將有因爲OP的數據是big-endian(根據他的問題),因此在使用小端編程體系結構(例如Intel x86/x64)上的內置.NET實現之前要進行交換。 –

1

你可以用不安全的代碼做到這一點:

fixed(byte* p = bytearray) 
{ 
    ushort* ptr=(ushort*)p; 
    for(int i = 0; i < bytearray.Length/2; i++) 
    { 
     //... 
    } 
} 
+0

這將不起作用,它將產生0x2211,0x4433等,而不是1122,3344 – Fredou

1

你不能施放整個陣列那樣的,至少不會在託管代碼。您可以使用BitConverter.ToUInt16轉換這一點,就像這樣:

UInt16[] uint16array = Enumerable 
    .Range(0, arr.Length/2) 
    .Select(i => BitConverter.ToUInt16(arr, 2*i)) 
    .ToArray(); 
+0

這將產生小問題endian行爲問題請求大端行爲。 – user12864

+0

這將工作,如果你在它的末尾實現,BitConverter.IsLittleEndian – Fredou