2010-12-09 1 views
1

Convertion от Double [] ЦСИ в Byte [] ДСТ может быть эффективно сделано в C# с помощью фиксированных указателей:Как преобразовать список <Double> в Byte [] в C#

fixed(Double* pSrc = src) 
{ 
    fixed(Byte* pDst = dst) 
    { 
    Byte* ps = (Byte*)pSrc; 
    for (int i=0; i < dstLength; i++) 
    { 
     *(pDst + i) = *(ps +i); 
    } 
    } 
} 

Как я могу сделать то же самое для Список src? I.e. как я могу получить фиксированный указатель на массив Double [] , включенный в список? Спасибо.

+2

Я даже не знаю, что-то подобное существует ... – 2010-12-09 15:30:17

+0

Я более любопытным зачем вы это делаете с помощью указателей? – Vitalik 2010-12-09 20:55:33

ответ

1

не уверен, что вы собираетесь, но я думаю ... вы хотите System.Runtime.Interopservices.Marshal.StructToPtr.

0

Используйте метод List<T>.ToArray() и оперируйте полученным массивом.

+0

Я не думаю, что это желательно, так как это означает, что создается третий массив, и значения копируются на него, поэтому потребление работы и памяти удваивается. – Monoman 2010-12-09 15:46:33

1

Вы всегда можете использовать метод ToArray() на объекте List<Double>, чтобы получить Double[].

1

Вы можете использовать отражение, чтобы получить ссылку на личное поле T [] _items в экземпляре List.

Предупреждение: В вашем фрагменте кода, вы должны убедиться, что dstLength является минимальным ДСТ и Src длины в байтах, так что вы не пытаетесь копировать больше байт, чем доступны. Вероятно, вы делаете это, создавая dst с точно таким же размером, чтобы соответствовать src, но ваш фрагмент не дает понять.

0

Почему бы вам не просто открыть список, как обычно?

List<double> list = new List<double>(); 
list.Add(Math.PI); 
list.Add(34.22); 

byte[] res = new byte[list.Count * sizeof(double)]; 

unsafe 
{ 
    fixed (byte* pres = res) 
    { 
     for (int i = 0; i < list.Count; i++) 
     { 
      *(((double*)pres) + i) = list[i]; 
     } 
    } 
} 

Я не тестировал его полностью и мне редко нужен небезопасный код, но он работает нормально.

Edit: здесь другой (имо предпочтительнее) раствор, без опасного кода:

int offset = 0; 
for (int i = 0; i < list.Count; i++) 
{ 
    long num = BitConverter.DoubleToInt64Bits(list[i]); 

    for (int j = 0; j < 8; j++) 
    { 
     res[offset++] = (byte)num; 
     num >>= 8; 
    } 
} 
0

Это может работать, но будем иметь данные loss- содержание массива будет 3 и 34.

List<double> list = new List<double>(); 
    list.Add(Math.PI); 
    list.Add(34.22); 

    byte[] arr = (from l in list 
        select (byte)l).ToArray<byte>(); 
0

Я использовал эти вспомогательные методы до:

byte[] GetBytesBlock(double[] values) 
{ 
    var result = new byte[values.Length * sizeof(double)]; 
    Buffer.BlockCopy(values, 0, result, 0, result.Length); 
    return result; 
} 

double[] GetDoublesBlock(byte[] bytes) 
{ 
    var result = new double[bytes.Length/sizeof(double)]; 
    Buffer.BlockCopy(bytes, 0, result, 0, bytes.Length); 
    return result; 
} 

Пример:

List<double> myList = new List<double>(){ 1.0, 2.0, 3.0}; 

//to byte[] 
var byteResult = GetBytesBlock(myList.ToArray()); 

//back to List<double> 
var doubleResult = GetDoublesBlock(byteResult).ToList();