簡體   English   中英

c#如何將struct數組轉換為數組結構

[英]c# how to convert array of struct to struct of array

我從一個IntPtr開始,從發送周期性數據包的硬件源中獲取結構化數據。 線程從Intptr緩沖區復制數據包並將byte []放入隊列。 稍后讀取隊列並使用此答案將byte []轉換為結構,並成為Packet類型的集合(數組)。

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

Packet[] array_of_packet; 

如果沒有復制結構定義,我想,如果它是陣列的結構來使用這些數據。

struct ArrayOfPacket {
  long[] time;
  int[] field1;
  short[] field2;
}

ArrayOfPacket data;  

此格式允許其他函數將它們用作向量:

Plot(data.time, data.field1);

如果你想要的只是一種轉換為數組的簡單方法,那么只需使用LINQ:

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

如果您正在尋找一種神奇的方法來重新排列內存中的數據而無需復制成本,那么您就不走運了。 ;-)

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這些屬性

一個更有效的解決方案可能是

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;

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

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]);}
    }

}

然后,使用這樣的簡單幫助方法:

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 struct添加到ArrayWrapper定義中,並讓ArrayWrapper將字節偏移量作為其構造函數參數,並執行一些unsafe魔法更快地訪問該字段的數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM