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
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 (.ctor
s) 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.