【问题标题】:A generic construct requires that the type 'Cell<'T>' is an unmanaged type泛型构造要求类型“Cell<'T>”是非托管类型
【发布时间】:2019-02-13 03:16:04
【问题描述】:

为什么我不能在 F# 中使用通用的非托管结构?可能是Cell&lt;'T when 'T: unmanaged&gt; 不是非托管的,那么我该如何解决呢?

type FloatCell =
    struct
        val x: float
        val y: nativeptr<FloatCell>
    end
    
[<Struct>]
[<StructLayout(LayoutKind.Sequential)>]
type Cell<'T when 'T: unmanaged> =
    struct
        val x: 'T
        val y: nativeptr<Cell<'T>>
    end   

给予

错误 FS0001:通用构造要求类型 'Cell' 是非托管类型 [E:\dzmitry\src\uncorefx\src\uncorefx\uncorefx.fsproj]

更新:

C# 也一样。

   unsafe struct FloatCell
    {
        public float val;
        public FloatCell* next;
    }

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    unsafe struct Cell<T> where T: unmanaged
    {
        public float val;
        public Cell<T>* next;
    }

有错误:

错误 CS0208:无法获取托管类型 ('Program.Cell') 的地址、大小或声明指向托管类型的指针

我不认为它是托管的。

更新 2:

我尝试了属性。没有帮助。 我已经使用扩展属性进行演员表。可能的解决方案。但是质疑为什么我不能在本地做到这一点?或者我能做到吗?还是我应该提出 C#/F# 问题?

[<Struct>]
[<NativeCppClass>]
[<System.Runtime.CompilerServices.UnsafeValueType>]
[<StructLayout(LayoutKind.Sequential)>]
type Cell<'T when 'T: unmanaged> =
    struct
        val element: 'T
        val next:  voidptr
    end    

type Cell<'T when 'T: unmanaged> with
    member  x.Next = x.next |> NativePtr.ofVoidPtr<'T> 

更新3:

我试图总结指针,并在没有指针的情况下进入问题。

    public struct UnmanagedStruct
    {
    }

    public struct UnmanagedStructWithSpecifiedGenerics
    {
        public EmptyCell<float> cell;
    }

    public ref struct RefUnmanagedStruct
    {
        public EmptyCell<float> cell;
    }

    public  struct EmptyCell<T> where T : unmanaged
    {
    }

然后实例化:

        var compiles1 = new UnmanagedStructWithSpecifiedGenerics();
        var compiles2 = new EmptyCell<UnmanagedStruct>();
        var CS8377_1 = new EmptyCell<EmptyCell<float>>();
        var CS8377_1 = new EmptyCell<UnmanagedStructWithSpecifiedGenerics>();
        var CS0306 = new EmptyCell<RefUnmanagedStruct>();

导致:

错误 CS8377:类型“EmptyCell”必须是不可为空的值类型,以及任何嵌套级别的所有字段,才能将其用作泛型类型或方法“EmptyCell”中的参数“T”

错误 CS8377:类型“UnmanagedStructWithSpecifiedGenerics”必须是不可为空的值类型,以及任何嵌套级别的所有字段,才能将其用作泛型类型或方法“EmptyCell”中的参数“T”

错误 CS0306:“RefUnmanagedStruct”类型不能用作类型参数

错误信息?我应该向 Roslyn 编译器提出问题吗?

【问题讨论】:

    标签: c# .net f# native unmanaged


    【解决方案1】:

    这似乎是设计使然,但我不确定限制的原因。这是F# spec的引述:

    5.2.9 非托管约束

    非托管约束具有以下形式: typar : unmanaged

    在约束求解期间(第 14.5 节),如果 type 如下所示为非托管,则满足约束 type : unmanaged:

    • @,char,float32,@ 9876543333,@,@,@ 987654333,@,@ 987654333,@,@ 987654333,@,@ 9876543333,@,@ 987654333,@,@ 987654333,@,@ 9876543332 @ @、uint64、decimal 不受管理。
    • 类型nativeptr&lt;type&gt; 是非托管的。
    • 其字段都是非托管类型的非泛型结构类型是非托管的。

    注意非泛型结构类型在最后一个项目符号中明确提及。

    【讨论】:

    • 我会尝试编译纯 IL 类,看看这是 C#/F# 还是 CLR 的限制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 2018-10-29
    • 2019-07-14
    • 1970-01-01
    • 2017-01-21
    相关资源
    最近更新 更多