代码之家  ›  专栏  ›  技术社区  ›  Zachary Turner

如何读取值类型的第n个字节

c#
  •  1
  • Zachary Turner  · 技术社区  · 13 年前

    假设我有一个如下定义的值类型:

    [StructLayout(LayoutKind.Explicit, Size=40)]
    public struct Storage
    {
    }
    

    这个类的唯一目的是占用40字节的内存。有没有一种方法可以轻松读取第n个字节?例如,我想编写以下函数:

    byte ReadFromStorage(ref Storage s, int n)
    {
    }
    

    并且类似地用于写入版本。我需要此函数的性能尽可能接近以下C代码:

    return *((char*)s + n);
    
    2 回复  |  直到 13 年前
        1
  •  1
  •   Ani    13 年前

    使用 Fixed Size Buffers 相反

    也就是说,没有什么能阻止你在 unsafe 上下文(假设您使用的是显式布局):

    unsafe byte ReadFromStorage(ref Storage s, int n)
    {
        fixed(Storage* ptr = &s)
        {
           return ((byte*)ptr)[n];
        }
    }
    
        2
  •  0
  •   sisve    13 年前

    没有理由为此使用不安全的代码。

    static byte ReadFromStorage(Storage s, int n) {
        var handle = default(GCHandle);
    
        try {
            handle = GCHandle.Alloc(s, GCHandleType.Pinned);
            var ptr = handle.AddrOfPinnedObject();
    
            var arrSize = Marshal.SizeOf(typeof(Storage));
            var arr = new Byte[arrSize];
            Marshal.Copy(ptr, arr, 0, arrSize);
            return arr[n];
    
        } finally {
            if (handle.IsAllocated)
                handle.Free();
        }
    }
    

    在反复修改并阅读了威廉的评论后,这只是一个电话 Marshal.ReadByte ,但这看起来并不像处理程序和try finally语句那样酷。

    var b = Marshal.ReadByte(s, n);