2015-04-02 49 views
2
約束

當我編譯下面的代碼:「非託管」 泛型參數在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,我看這是什麼地方,在「emdbedded簽名文件」。那是什麼?

+0

可能重複http://stackoverflow.com/questions/ 27693910/f-unmanaged-type-constraint的行爲) – thehennyy 2015-04-03 00:35:17

+0

@thehennyy該問題主要是關於行爲,並沒有完全回答我的問題。 – IllidanS4 2015-04-03 09:40:59

+0

[此答案](http://stackoverflow.com/a/21338079/82959)對嵌入式簽名/優化數據有更深入的瞭解。 – kvb 2015-04-04 13:33:19

回答

1

這些約束位於存儲在FSharpSignatureData實體數據管理資源。它可以使用F#元數據讀取器從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); 
的([F# 「非託管」 類型的約束行爲]