When I compile the following code:
type Class1<'T when 'T : unmanaged> =
class end
type Class2<'T> =
class end
in IL it looks like this:
.class auto ansi serializable nested public Class1`1<T> extends [mscorlib]System.Object
.class auto ansi serializable nested public Class2`1<T> extends [mscorlib]System.Object
Is the unmanaged
constraint saved somewhere? If so, where and how can I programatically obtain it?
In this question, I read it is somewhere in the "emdbedded signature file". What is that?
These constraint are located in the entity data stored in FSharpSignatureData managed resource. It is possible to browse them using F# Metadata Reader from F# PowerPack:
public static IList<FSharpGenericParameterConstraint> GetFSharpGenericParameterConstraints(Type genericType, int position)
{
return GetFSharpGenericParameterConstraints(genericType.GetGenericArguments()[position]);
}
public static IList<FSharpGenericParameterConstraint> GetFSharpGenericParameterConstraints(Type genericParameter)
{
var declMethod = genericParameter.DeclaringMethod;
var declType = genericParameter.DeclaringType;
var fsAsm = FSharpAssembly.FromAssembly(genericParameter.Assembly);
int pos = genericParameter.GenericParameterPosition;
var entities = AllEntities(fsAsm.Entities);
if(declMethod != null)
{
var member = entities.SelectMany(e => e.MembersOrValues).First(m => m.ReflectionMemberInfo == declMethod);
return member.GenericParameters[pos].Constraints;
}else if(declType != null)
{
var entity = entities.First(e => e.ReflectionType == declType);
return entity.GenericParameters[pos].Constraints;
}
return null;
}
private static IEnumerable<FSharpEntity> AllEntities(IEnumerable<FSharpEntity> entities)
{
return entities.Concat(entities.SelectMany(e => AllEntities(e.NestedEntities)));
}
bool unmanaged = GetFSharpGenericParameterConstraints(typeof(MyModule.Class1<>), 0).Any(c => c.IsUnmanagedConstraint);