"非托管" IL中的泛型参数约束

时间:2015-04-02 23:40:24

标签: reflection f# cil il

编译以下代码时:

type Class1<'T when 'T : unmanaged> =
    class end

type Class2<'T> =
    class end
IL中的

看起来像这样:

.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

unmanaged约束是否保存在某处?如果是这样,我可以在哪里以及如何以编程方式获得它?

this question中,我读到了#34; emdbedded签名文件&#34;中的某个地方。那是什么?

1 个答案:

答案 0 :(得分:1)

这些约束位于存储在FSharpSignatureData受管资源中的实体数据中。可以使用F# PowerPack中的F#元数据阅读器浏览它们:

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);