没有什么能比exyi提供的解决方案的性能更好。我对unsafe
代码没有任何问题,但是相应的BitConverter
类方法(http://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs)中的某些东西真的让我很担心——它们会进行对齐检查,并对未对齐的情况使用不同的实现。下面是一个更安全的纯 C# 解决方案 - 它可能有点慢(但应该测量,你永远不知道),但应该比原来的快得多。作为奖励,我添加了显式名称方法(类似于 中的那些BitConverter
)除了使用bytes.To<int>()
(这还可以,但有点奇怪),您可以使用更方便bytes.ToInt32()
(应该比通用方法更快)。
public static class BitConverter<T> where T : struct
{
public static readonly Func<byte[], int, T> To = GetFunc();
static Func<byte[], int, T> GetFunc()
{
var type = typeof(T);
if (type == typeof(bool)) return Cast(BitConverter.ToBoolean);
if (type == typeof(sbyte)) return Cast(Extensions.ToSByte);
if (type == typeof(byte)) return Cast(Extensions.ToByte);
if (type == typeof(short)) return Cast(BitConverter.ToInt16);
if (type == typeof(ushort)) return Cast(BitConverter.ToUInt16);
if (type == typeof(int)) return Cast(BitConverter.ToInt32);
if (type == typeof(uint)) return Cast(BitConverter.ToUInt32);
if (type == typeof(long)) return Cast(BitConverter.ToInt64);
if (type == typeof(ulong)) return Cast(BitConverter.ToUInt64);
if (type == typeof(float)) return Cast(BitConverter.ToSingle);
if (type == typeof(double)) return Cast(BitConverter.ToDouble);
throw new NotSupportedException();
}
static Func<byte[], int, T> Cast<U>(Func<byte[], int, U> func) { return (Func<byte[], int, T>)(object)func; }
}
public static class Extensions
{
public static bool ToBoolean(this byte[] bytes, int offset = 0) { return BitConverter.ToBoolean(bytes, offset); }
public static sbyte ToSByte(this byte[] bytes, int offset = 0) { return unchecked((sbyte)bytes[offset]); }
public static byte ToByte(this byte[] bytes, int offset = 0) { return bytes[offset]; }
public static short ToInt16(this byte[] bytes, int offset = 0) { return BitConverter.ToInt16(bytes, offset); }
public static ushort ToUInt16(this byte[] bytes, int offset = 0) { return BitConverter.ToUInt16(bytes, offset); }
public static int ToInt32(this byte[] bytes, int offset = 0) { return BitConverter.ToInt32(bytes, offset); }
public static uint ToUInt32(this byte[] bytes, int offset = 0) { return BitConverter.ToUInt32(bytes, offset); }
public static long ToInt64(this byte[] bytes, int offset = 0) { return BitConverter.ToInt64(bytes, offset); }
public static ulong ToUInt64(this byte[] bytes, int offset = 0) { return BitConverter.ToUInt64(bytes, offset); }
public static float ToSingle(this byte[] bytes, int offset = 0) { return BitConverter.ToSingle(bytes, offset); }
public static double ToDouble(this byte[] bytes, int offset = 0) { return BitConverter.ToDouble(bytes, offset); }
public static T To<T>(this byte[] bytes, int offset = 0) where T : struct { return BitConverter<T>.To(bytes, offset); }
}