泛型方法使用BitConverter.GetBytes

问题描述 投票:1回答:2

我试图让使用BitConverter.GetBytes不同类型的不同对象的字节。为了做到这一点,我想编写一个通用的扩展方法,而不是写每一个类型的我想(短,长,ULONG等)工作的个人扩展方法。

这可能吗?

这里的(不工作)的代码,我至今对泛型方法:

public static byte[] Foo<T>(this T input) where T : struct
{
    // error here, no match to overloads
    var result = BitConverter.GetBytes(input);
    // do more logic here...
    return result;
}

顺便说一句,这一定是.NET 3.5兼容。

c# generics bitconverter
2个回答
2
投票

这不建议,但你可以动态调用BitConverter.GetBytes方法:

public static byte[] ToFlipped<T>(T input) where T : struct
{
    var result = (byte[])typeof(BitConverter).GetMethod("GetBytes", new[] { typeof(T) })
        .Invoke(null, new[] { input });
    Array.Reverse(result);

    return result;
}

1
投票

使用GCHandle.Alloc()和钉扎结构:-)

public static byte[] Foo<T>(this T input) where T : struct
{
  int size = Marshal.SizeOf(typeof(T));
  var result = new byte[size];
  var gcHandle = GCHandle.Alloc(input, GCHandleType.Pinned);
  Marshal.Copy(gcHandle.AddrOfPinnedObject(), result, 0, size);
  gcHandle.Free();
  return result;
}

......但“Marshal.SizeOf”给出了布尔和字符错误的大小。

我有rewritte sizeof运算功能(看起来有点疯狂,但其极端的快)

static readonly Dictionary<long, int> SizeOfDict = new Dictionary<long, int>();

//[MethodImpl(MethodImplOptions.AggressiveInlining)] // not supported below 4.5
public static int SizeOf<T>() where T : struct
{
  // --- Highspeed Compiler-Hack ---
  // if (typeof(T) == typeof(byte)) return sizeof(byte); // uncomment if .Net >= 4.5
  // if (typeof(T) == typeof(sbyte)) return sizeof(sbyte);
  // if (typeof(T) == typeof(ushort)) return sizeof(ushort);
  // if (typeof(T) == typeof(short)) return sizeof(short);
  // if (typeof(T) == typeof(uint)) return sizeof(uint);
  // if (typeof(T) == typeof(int)) return sizeof(int);
  // if (typeof(T) == typeof(ulong)) return sizeof(ulong);
  // if (typeof(T) == typeof(long)) return sizeof(long);
  // if (typeof(T) == typeof(float)) return sizeof(float);
  // if (typeof(T) == typeof(double)) return sizeof(double);
  // --- fix wrong sizes ---
  if (typeof(T) == typeof(char)) return sizeof(char);
  if (typeof(T) == typeof(bool)) return sizeof(bool);
  long id = (long)typeof(T).TypeHandle.Value;
  int len;
  if (!SizeOfDict.TryGetValue(id, out len))
  {
    len = Marshal.SizeOf(typeof(T));
    SizeOfDict.Add(id, len);
  }
  return len;
}
© www.soinside.com 2019 - 2024. All rights reserved.