Поведение стиля reinterpret_cast
Если вы немного манипулируете, то это может быть невероятно полезным
Многие высокопроизводительные реализации хеш-кода используют UInt32 для значения хеш-кода (это упрощает сдвиги). Поскольку .Net требует Int32 для метода, вы хотите быстро преобразовать uint в int. Поскольку не имеет значения, каково действительное значение, только для того, чтобы все биты в значении были сохранены, требуется переинтерпретация.
public static unsafe int UInt32ToInt32Bits(uint x)
{
return *((int*)(void*)&x);
}
обратите внимание, что именование смоделировано на BitConverter.DoubleToInt64Bits
Продолжая в духе хеширования, преобразование основанной на стеке структуры в байт * позволяет легко использовать функции байтового хеширования:
// from the Jenkins one at a time hash function
private static unsafe void Hash(byte* data, int len, ref uint hash)
{
for (int i = 0; i < len; i++)
{
hash += data[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
}
public unsafe static void HashCombine(ref uint sofar, long data)
{
byte* dataBytes = (byte*)(void*)&data;
AddToHash(dataBytes, sizeof(long), ref sofar);
}
также небезопасно (начиная с версии 2.0) позволяет использовать stackalloc. Это может быть очень полезно в ситуациях с высокой производительностью, когда требуется небольшой массив переменной длины, например временное пространство.
Все эти виды использования будут полностью «только в том случае, если ваше приложение действительно нуждается в производительности» и, таким образом, неприемлемы для общего использования, но иногда вам действительно это нужно.
fixed необходим, когда вы хотите взаимодействовать с какой-нибудь полезной неуправляемой функцией (их много), которая принимает массивы или строки в стиле c. Таким образом, в сценариях взаимодействия это касается не только соображений производительности, но и корректности.