2016-09-29 194 views
1

我從一個IntPtr開始從發送週期性數據包的硬件來源的結構化數據。線程從Intptr緩衝區複製一個數據包,並將byte []放入隊列中。稍後讀取隊列並使用this answer將byte []轉換爲結構,併成爲Packet類型的集合(數組)。c#如何將結構數組轉換爲數組結構

struct Packet { 
    long time; 
    int field1; 
    short field2; 
} 

Packet[] array_of_packet; 

沒有複製結構定義,我想使用數據,好像它是陣列的結構。

這種格式允許其他功能使用它們作爲載體:

Plot(data.time, data.field1); 
+0

我輸了!無論如何,它應該是很長的時間,而不是很長的時間[] – Nair

+0

那麼,這是一個完全不同的佈局。您需要手動逐項複製所有內容。 – Luaan

+0

你真的應該看看創建[不可變結構](http://stackoverflow.com/questions/3751911/why-are-c-sharp-structs-immutable)。 – juharr

回答

3

如果你想要的是一個簡單的方法來轉換成數組,然後只使用LINQ:

Plot (array_of_packet.Select(p => p.time).ToArray(), 
     array_of_packet.Select(p => p.field1).ToArray()); 

如果你正在尋找一種神奇的方式來重新排列內存中的數據,而不需要複製的代價,那麼你的運氣不好。 ;-)

0

很容易使用LINQ

data.time = array_of_packet.Select(p => p.time).ToArray(); 
data.field1 = array_of_packet.Select(p => p.field1).ToArray(); 
data.field2 = array_of_packet.Select(p => p.field2).ToArray(); 

雖然你需要做的屬性public

更effecient解決方案可能是

var time = new long[array_of_packet.Length]; 
var field1 = new int[array_of_packet.Length]; 
var field2 = new short[array_of_packet.Length]; 
for(int i = 0; i < array_of_packet.Length; i++) 
{ 
    time[i] = array_of_paket[i].time; 
    field1[i] = array_of_paket[i].field1; 
    field2[i] = array_of_paket[i].field2; 
} 

data.time = time; 
data.field1 = field1; 
data.field2 = field2; 
0

您可以創建一個包裝類提供了一個類似數組的訪問器語法:

class ArrayWrapper<T, TField> 
{ 
    Func<T, TField> getField; 
    T[] array; 

    public ArrayWrapper(T[] array, Func<T, TField> getField) 
    { 
     this.array = array; 
     this.getField = getField; 
    } 

    public TField this[int index] 
    { 
     get { return this.getField(this.array[index]);} 
    } 

} 

然後,用一個簡單的helper方法是這樣的:

ArrayWrapper<T, TField> Wrap<T, TField>(T[] array, Func<T, TField> getField) 
{ 
    return new ArrayWrapper<T, TField>(array, getField); 
} 

您可以創建這樣一個對象:

var data = new 
{ 
    time = Wrap(array_of_packet, p => p.time), 
    field1 = Wrap(array_of_packet, p => p.field1), 
    field2 = Wrap(array_of_packet, p => p.field2) 
}; 

...它可用於你想要的方式:

Plot(data.time, data.field1); 

根據您的具體需求,您可以通過多種方式詳細說明:

  • 使類實現一個像IList<TField>這樣的接口,以便Plot()可以以不知底層類型的方式編寫。 (陣列已經實現了IList<TField>。)
  • 如果性能是高優先級,而不是使用一個委託(Func<,>),你可以添加where T is structArrayWrapper定義,並有ArrayWrapper採取字節作爲其構造函數的參數偏移,並做一些unsafe魔法可以更快地訪問該字段的數據。
+1

當我問這個問題 - 這就是我正在尋找的 - – pathfinder

+0

@brainfog:我認爲這可能是。我喜歡LINQ,但它聽起來像你試圖避免將數據複製到多個數組中。 – StriplingWarrior

+0

最初我一直在想它:1)收集數據2)轉換爲結構和它們的數組3)轉換爲數組結構而不用重新輸入原始結構(因爲我有很多他們之後可能會改變) – pathfinder