Behavior of F# “unmanaged” type constraint

后端 未结 3 531
猫巷女王i
猫巷女王i 2021-01-01 13:58

F# supports a type constraint for \"unmanaged\". This is not the same as a value type constraint like \"struct\" constraints. MSDN notes that the behavior of the unmanaged

3条回答
  •  轮回少年
    2021-01-01 14:57

    So, opening a small sample in ILDasm, we see the following F# code

    open System.Collections
    
    type Class1<'T when 'T : unmanaged> =
       class end
    
    type Class2<'T> =
        class end
    
    type Class3<'T when 'T :> IEnumerable> =
        class end
    

    becomes the following IL

    .class public auto ansi serializable beforefieldinit FSharpLibrary.Class1`1
           extends [mscorlib]System.Object
    {
      .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) 
    } // end of class FSharpLibrary.Class1`1
    
    .class public auto ansi serializable beforefieldinit FSharpLibrary.Class2`1
           extends [mscorlib]System.Object
    {
      .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) 
    } // end of class FSharpLibrary.Class2`1
    
    .class public auto ansi serializable beforefieldinit FSharpLibrary.Class3`1<([mscorlib]System.Collections.IEnumerable) T>
           extends [mscorlib]System.Object
    {
      .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) 
    } // end of class FSharpLibrary.Class3`1
    

    Notably, Class2 has an unconstrained generic parameter, and perfectly matches Class1 even though T is constrained to unmanaged in Class1. By contrast, Class3 does not match this given pattern, and we can clearly see the explicit :> IEnumerable constraint in IL.

    In addition, the following C# code

    public class Class2
    { }
    
    public class Class3
        where T : IEnumerable
    { }
    

    Becomes

    .class public auto ansi beforefieldinit CSharpLibrary.Class2`1
           extends [mscorlib]System.Object
    {
    } // end of class CSharpLibrary.Class2`1
    
    .class public auto ansi beforefieldinit CSharpLibrary.Class3`1<([mscorlib]System.Collections.IEnumerable) T>
           extends [mscorlib]System.Object
    {
    } // end of class CSharpLibrary.Class3`1
    

    Which, with the exception of the F#-generated constructors (.ctors) and Serializable flags, matches the F# generated code.

    With no other references to Class1 Thus means that the compiler is not, at the IL level, taking into account the unmanaged constraint, and leave no futher references to its presence in the compiled output.

提交回复
热议问题