为什么通用结构不能不受管理?
Why generic structs cannot be unmanaged?
请看这段代码:
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>>();
}
}
}
编译失败错误:
The type 'MyPoorGenericStructThatCannotBeUnmanaged' 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'
然而MyPoorGenericStructThatCannotBeUnmanaged<int>
是一个不可空值类型,它在任何嵌套值处的所有字段确实是不可空值类型。它由泛型类型约束 where T: unmanaged
确保
为什么?
在解决限制之前,您可以使用基于不安全的解决方法。
解决方法可能如下所示:
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));
}
}
}
请看这段代码:
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>>();
}
}
}
编译失败错误:
The type 'MyPoorGenericStructThatCannotBeUnmanaged' 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'
然而MyPoorGenericStructThatCannotBeUnmanaged<int>
是一个不可空值类型,它在任何嵌套值处的所有字段确实是不可空值类型。它由泛型类型约束 where T: unmanaged
为什么?
在解决限制之前,您可以使用基于不安全的解决方法。
解决方法可能如下所示:
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));
}
}
}