为什么通用结构体不能是非托管的?

3
请看这段代码:
namespace ConsoleApp
{
    public struct MyPoorGenericStructThatCannotBeUnmanaged<T> where T: unmanaged
    {
        public T Field;
    }

    public class MyClass<T> where T: unmanaged
    {
    }

    class Program
    {
        static void Main()
        {
            // The type 'MyPoorGenericStructThatCannotBeUnmanaged<int>' must be a non-nullable value type, 
            // along with all fields at any level of nesting, 
            // in order to use it as parameter 'T' in the generic type or method 'MyClass<T>'
            var obj = new MyClass<MyPoorGenericStructThatCannotBeUnmanaged<int>>(); 
        }
    }
}

它编译失败并显示错误消息:
“MyClass”的参数“T”必须为非空值类型,并且在嵌套的任何级别上所有字段也必须为非空值类型,才能将其用作泛型类型或方法的参数。”
然而,MyPoorGenericStructThatCannotBeUnmanaged<int> 是一个非空值类型,它嵌套的任何级别上的所有字段都是非空值类型。这是通过泛型类型约束where T:unmanaged来确保的。
为什么?

1
已知限制。正在努力解决中。 - Jeroen Mostert
1个回答

0

在限制问题得到解决之前,您可以使用基于 Unsafe 的解决方法。

以下是解决方法的示例:

public unsafe class ArrayOfGenericStructs<TStruct> : IDisposable where TStruct:struct
{
    private void* pointer;

    public ArrayOfGenericStructs(int size)
    {
        pointer = (void*) Marshal.AllocHGlobal(Unsafe.SizeOf<TStruct>() * size);
    }

    public bool IsDisposed { get; private set; }

    public void Dispose()
    {
        if (IsDisposed) return;
        IsDisposed = true;
        if (pointer != null) Marshal.FreeHGlobal(new IntPtr(pointer));
        pointer = null;
    }

    public ref TStruct this[int index]
    {
        get
        {
            return ref Unsafe.AsRef<TStruct>(Unsafe.Add<TStruct>(pointer, index));
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接