可以匹配您尝试做的方法是Marshal.Copy,但它不需要适当的参数来制作通用方法。
尽管不可能编写具有通用约束的通用方法来描述可能的情况,但并非每种类型都可以使用“不安全”的方式进行复制。有一些例外;类就是其中之一。
这是一个示例代码:
    public unsafe static T[] Create<T>(void* source, int length)
    {
        var type = typeof(T);
        var sizeInBytes =  Marshal.SizeOf(typeof(T));
        T[] output = new T[length];
        if (type.IsPrimitive)
        {
            // Make sure the array won't be moved around by the GC 
            var handle = GCHandle.Alloc(output, GCHandleType.Pinned);
            var destination = (byte*)handle.AddrOfPinnedObject().ToPointer();
            var byteLength = length * sizeInBytes;
            // There are faster ways to do this, particularly by using wider types or by 
            // handling special lengths.
            for (int i = 0; i < byteLength; i++)
                destination[i] = ((byte*)source)[i];
            handle.Free();
        }
        else if (type.IsValueType)
        {
            if (!type.IsLayoutSequential && !type.IsExplicitLayout)
            {
                throw new InvalidOperationException(string.Format("{0} does not define a StructLayout attribute", type));
            }
            IntPtr sourcePtr = new IntPtr(source);
            for (int i = 0; i < length; i++)
            {
                IntPtr p = new IntPtr((byte*)source + i * sizeInBytes);
                output[i] = (T)System.Runtime.InteropServices.Marshal.PtrToStructure(p, typeof(T));
            }
        }
        else 
        {
            throw new InvalidOperationException(string.Format("{0} is not supported", type));
        }
        return output;
    }
    unsafe static void Main(string[] args)
    {
        var arrayDouble = Enumerable.Range(1, 1024)
                                    .Select(i => (double)i)
                                    .ToArray();
        fixed (double* p = arrayDouble)
        {
            var array2 = Create<double>(p, arrayDouble.Length);
            Assert.AreEqual(arrayDouble, array2);
        }
        var arrayPoint = Enumerable.Range(1, 1024)
                                   .Select(i => new Point(i, i * 2 + 1))
                                   .ToArray();
        fixed (Point* p = arrayPoint)
        {
            var array2 = Create<Point>(p, arrayPoint.Length);
            Assert.AreEqual(arrayPoint, array2);
        }
    }
该方法可以是泛型的,但它不能采用泛型类型的指针。这不是问题,因为指针协方差有帮助,但这具有阻止泛型参数类型的隐式解析的不幸效果。然后,您必须明确指定 MakeArray。
我为结构添加了一个特殊情况,最好使用指定struct layout的类型。在您的情况下,这可能不是问题,但如果指针数据来自本机 C 或 C++ 代码,则指定布局类型很重要(CLR 可能会选择重新排序字段以获得更好的内存对齐)。
但是,如果指针完全来自托管代码生成的数据,那么您可以删除检查。
此外,如果性能是一个问题,那么有更好的算法来复制数据而不是逐字节地复制数据。(参考memcpy的无数实现)