В целях тестирования я хочу сравнить две структуры (неизвестного типа T), выделенные из неуправляемого кода.
Поскольку они могут содержать некоторую упаковку в неуправляемом представлении, нецелесообразно преобразовывать всю структуру в байтовый массив, а затем сравнивать побайтно:
int size = Marshal.SizeOf(typeof(T));
IntPtr buf1 = Marshal.AllocHGlobal(size); // FreeHGlobal omitted for simplicity
IntPtr buf2 = Marshal.AllocHGlobal(size);
byte[] array1 = new byte[size];
byte[] array2 = new byte[size];
Marshal.StructureToPtr(st1, buf1, false);
Marshal.StructureToPtr(st2, buf2, false);
Marshal.Copy(buf1, array1, 0, size);
Marshal.Copy(buf2, array2, 0, size);
// inapropriate
for (int i = 0; i < size; ++i)
{
if (array1[i] != array2[i]) { return false; }
}
return true;
Я думаю, что необходимо сравнивать поле за полем.
Благодаря рефлексии я могу перечислить FieldInfo, а затем, используя метод Marshal.OffsetOf, получить смещения полей.
К сожалению, однако, я понятия не имею, как получить размеры полей.
Без этого я не смогу сравнить два поля, исключая эффект упаковки.
foreach (var fieldInfo in typeof(T).GetFields())
{
int offset = (int)Marshal.OffsetOf(typeof(T), fieldInfo.Name);
int fieldSize = ...; // I need this
for (int i = offset; i < offset + fieldSize; ++i)
{
if (array1[i] != array2[i]) { return false; }
}
}
return true;
Есть ли способ сделать это?
Или есть лучший способ сравнить неуправляемые структуры?
Примечание:
Типы полей являются произвольными (могут быть примитивные целые числа, массивы, строки, перечисления, структуры и т. Д.).